acwing 1050. 鸣人的影分身 dfs,dp

71 阅读2分钟

1050. 鸣人的影分身 - AcWing题库

dfs解法

这道题看见第一面就是dfs解法,注意组合情况别考虑成员有0的情况,不然会栈溢出到你怀疑人生

#include <bits/stdc++.h>
using namespace std;
int m, n;

vector<vector<int>>vv;
vector<int>v;

void dfs(int index, int sum, int target) {
	if (sum == target && v.size() == n) {  //v.size()==n这个条件一定要加上,不然每次不一定是1取3个,可能取4个,5个^
		vv.push_back(v);
		return;
	}

	for (int i = index; i <= target; i++) {


		//一定要剪枝,不然光样例就要跑4,5秒,因为样例的target是8,也就是遍历8!
		if (sum >= target)
			break;


		v.push_back(i);
		sum += i;
		dfs(i, sum, target); //可以取重复的,所以i不+1
		v.pop_back();
		sum -= i;
	}
}

int main() {

	int  t;
	cin >> t;
	while (t--) {
		cin >> m >> n;

		dfs(1, 0, m); //注意index从1开始不要从0开始,0+小于target的任何数都不会等于target,就会一直找下去了

//		for (auto &it : vv) {
//			for (auto num : it) {
//				cout << num << " ";
//			}
//			cout << endl;
//		}
		int len = vv.size();

		cout << len << endl;
	}


	return 0;
}

DP解法

这道题我画了DP图如下: image.png 我来解释一下状态计算推出来的公式:

这道题我们可以转换为是m个苹果放n个盘子的问题。

那么有两种情况

一.有一个盘子如果不放东西,那么苹果就只能放在剩下的两个盘子里。

那么就把盘子个数-1,苹果怎么放都放在两个盘子之间分配。 表示为f(m,n-1)

二.如果所有的盘子都放苹果,那么要保证每个盘子至少都放1个苹果。

可以用m-n,先往每个盘子里放1个苹果,然后再把剩下的苹果在n个盘子里分配。表示为f(m-n,n)

如果两个盘子都不放苹果呢?这种情况只有一种组合:0 0 7(所有顺序都是一种组合),这种情况包含在只有一个盘子不放苹果的情况里。

Code

image.png