整数划分(二)
时间限制:
1000 ms | 内存限制:
65535 KB
难度:
3
-
描述
-
把一个正整数m分成n个正整数的和,有多少种分法?
例:把5分成3个正正数的和,有两种分法:
1 1 3
1 2 2
-
输入
-
第一行是一个整数T表示共有T组测试数据(T<=50)
每组测试数据都是两个正整数m,n,其中(1<=n<=m<=100),分别表示要拆分的正数和拆分的正整数的个数。
输出
-
输出拆分的方法的数目。
样例输入
-
2 5 2 5 3
样例输出
-
2
2
-
-
**动态规划具体思路如下,
-
-
设dp[i][j]为将i划分为j个整数的划分数。
(1) i<j为不可能出现的情况,dp[i][j]=0;
(2) 若i=j,有一种情况:i可以划分为i个1之和,dp[i][j]=1;
(3) 若i>j,可以根据划分数中是否含有1分为两类:若划分数中含有1,可以使用“截边法”将j个划分分别截去一个1,把问题转化为i-1的j-1个划分数,为dp[i-1][j-1]; 若划分中不包含1,使用“截边法”将j个划分数的最下面一个数截去,将为题转化为求i-j的j个划分数,为dp[i-j][j]。所以i>j时dp[i][j]=dp[i-1][j-1]+dp[i-j][j]。
-
#include <iostream> #include <cstring> using namespace std; int dp[110][110]; int main() { int N; cin>>N; while(N--) { int m,n,i,j; cin>>m>>n; memset(dp,0,sizeof(dp)); for(i=1;i<=m;i++) { for(j=1;j<=n;j++) { if(j>i) dp[i][j] = 0; else if(j==i) dp[i][j] = 1; else dp[i][j] = dp[i-1][j-1] + dp[i-j][j]; } } cout<<dp[m][n]<<endl; } return 0; }
-
-
第一行是一个整数T表示共有T组测试数据(T<=50)