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图如下:
我来解释一下状态计算推出来的公式:
这道题我们可以转换为是m个苹果放n个盘子的问题。
那么有两种情况
一.有一个盘子如果不放东西,那么苹果就只能放在剩下的两个盘子里。
那么就把盘子个数-1,苹果怎么放都放在两个盘子之间分配。 表示为f(m,n-1)
二.如果所有的盘子都放苹果,那么要保证每个盘子至少都放1个苹果。
可以用m-n,先往每个盘子里放1个苹果,然后再把剩下的苹果在n个盘子里分配。表示为f(m-n,n)
如果两个盘子都不放苹果呢?这种情况只有一种组合:0 0 7(所有顺序都是一种组合),这种情况包含在只有一个盘子不放苹果的情况里。
Code