题目描述
将整数n分成k份,且每份不能为空,任意两份不能相同(不考虑顺序)。
例如:n=7,k=3,下面三种分法被认为是相同的。
1,1,5; 1,5,1; 5,1,1;
问有多少种不同的分法。
输入:n,k ( 6 < n ≤ 200,2 ≤ k ≤ 6 )
输出:一个整数,即不同的分法。
例如:n=7,k=3,下面三种分法被认为是相同的。
1,1,5; 1,5,1; 5,1,1;
问有多少种不同的分法。
输入:n,k ( 6 < n ≤ 200,2 ≤ k ≤ 6 )
输出:一个整数,即不同的分法。
输入描述:
两个整数 n,k ( 6 < n ≤ 200, 2 ≤ k ≤ 6 )
输出描述:
1个整数,即不同的分法。
示例1
输入
7 3
输出
4
解答
1、把n划分为k个,那么先从n中拿一个x,题目便变为将(n-x)分为m-1种,为了防止不会发生重复的情况,要保证每次拿的x不会比上一次拿的x要小,所以我们可以依次拿一个1出来,递推式为,即有1的情况;
2、没有1的情况,可以看成为j个元素预分配一个1,剩下的便没有1,即。故当时便有了递推式。
3、要注意当j为1时只有一种,当j为0时则不存在;当i为1或0时则不存在。
2、没有1的情况,可以看成为j个元素预分配一个1,剩下的便没有1,即。故当时便有了递推式。
3、要注意当j为1时只有一种,当j为0时则不存在;当i为1或0时则不存在。
代码:
#include <iostream> #include <cstdio> #include <algorithm> int f[205][10]; using namespace std; int main() { int n,k; scanf("%d%d",&n,&k); for(int i=1;i<=n;i++) { f[i][1]=1; //将i划分成1份肯定只有一种 f[i][0]=1; //将i划分成0份肯定不存在 } for(int i=2;i<=k;i++) { f[1][i]=0; //将1划分成i份(i>1)肯定不存在 f[0][i]=0; //将0划分成i份(i>1)肯定不存在 } for(int i=2;i<=n;i++) { for(int j=2;j<=k;j++) { if(i>j) f[i][j]=f[i-1][j-1]+f[i-j][j]; else //i<=j的情况 f[i][j]=f[i-1][j-1]; } } printf("%d",f[n][k]); return 0; }
来源:RollerCompaction