整数划分(二)
时间限制:
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
-
第一行是一个整数T表示共有T组测试数据(T<=50)
i表示数字大小,j表示拆分成几个数的和
对于dp[i][j]表示将i分成j个整数有几种方案;
dp[i-1][j-1],将i分出一个1放在组合的第一位,后面的方案和[i-1][j-1]相同
dp[i-j][j],此时的是非1的情况,即j个整数中都没有1的存在,此时{x1,x2...xj},一共j个元素;
看起来无从下手,但是,如果我把其中的每一个元素都减1,此时恰好方案和[i-j][j]的方案相同
由此得出公式:
dp[i][j]=dp[i-1][j-1]+dp[i-j][j]
#include <iostream>
#include<stdio.h>
#include<string.h>
#include<algorithm>
#include<vector>
#include<math.h>
#define mem(a,b) memset(a,b,sizeof(a))
using namespace std;
int main()
{
int dp[105][105]= {1};
for(int i=1; i<=100; i++)
{
for(int j=1; j<=i; j++)
{
dp[i][j]=dp[i-1][j-1]+dp[i-j][j];
}
}
int t,n,m;
scanf("%d",&t);
while(t--)
{
scanf("%d%d",&n,&m);
printf("%d\n",dp[n][m]);
}
}