DP问题状态表示,状态划分不太好想,一旦有了想法,代码是不复杂的。
/*
状态表示:f[i][j] 表示总和是i分成j个数的方案数
状态计算:
-分成j个数中最小值是0 -> f[i][j - 1] 【原方案数因为最小值是0, 所以在组成i的j个数中去掉一个数(0)还是原方案数,即f[i][j - 1]】
-分成j个数中最小值大于0 -> f[i - j][j] 【原方案数等于将所有数减去j个1的方案数,即f[i - j][j]】
状态转移方程:f[i][j] = f[i][j - 1] + f[i - j][j];
*/
#include<iostream>
#include<cstring>
using namespace std;
int T;//T组测试数据
int m, n; //m的查克拉,分成n个分身
int f[15][15];//dp状态数组
int main(){
cin >> T;
while(T--){
cin >> m >> n;
memset(f, 0, sizeof(f));//计算每组测试数据之前,清空f数组
f[0][0] = 1;//表示查克拉总和是0分成0个分身,也是一种方案
for(int i = 0; i <= m; i++)
for(int j = 1; j <= n; j++){
f[i][j] += f[i][j - 1];//情况1,一定存在
if(i >= j) f[i][j] += f[i - j][j];//情况2,只有在i>=j的时候存在
}
cout << f[m][n] << endl;//根据状态表示,答案就是查克拉值是m,分成n个分身的所有方案
}
return 0;
}