题目描述

将整数n分成k份,且每份不能为空,任意两份不能相同(不考虑顺序)。
例如: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时则不存在。

代码:
#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