数的划分
题目描述
将整数nnn分成kkk份,且每份不能为空,任意两个方案不相同(不考虑顺序)。
例如:n=7,k=3n=7,k=3n=7,k=3,下面三种分法被认为是相同的:
1,1,5; 1,5,1; 1,1,5.
问有多少种不同的分法。
输入格式
两个整数,nnn和kkk 。
输出格式
输出不同的分法数。
输入样例
7 3
输出样例
4
样例说明
四种分法为:1,1,5; 1,2,4; 1,3,3; 2,2,3.
思路
设f(i,j)f(i,j)f(i,j)表示整数iii分成jjj风的方案数,显然i<ji<ji<j时f(i,j)=0f(i,j)=0f(i,j)=0,i=ji=ji=j时f(i,j)=1f(i,j)=1f(i,j)=1。
其他的状态我们考虑两种情况:
1、jjj份中至少要有一份为1,显然方案书为f(i−1,j−1)f(i-1,j-1)f(i−1,j−1)。
2、jjj份中一份1都没有,我们考虑先将i−ji-ji−j分成jjj份,再往jjj份中的每一份加1,方案数为f(i−j,j)f(i-j,j)f(i−j,j)。
故有递推式:f(i,j)=f(i−1,j−1)+f(i−j,j)(i>j)f(i,j)=f(i-1,j-1)+f(i-j,j)(i>j)f(i,j)=f(i−1,j−1)+f(i−j,j)(i>j)
代码
#include<iostream>
#include<cstdio>
#include<algorithm>
using namespace std;
int f[300][100];
int main()
{
int n,k;
cin>>n>>k;
for(int i=1;i<=n;i++)
for(int j=1;j<=k;j++)
{
if(j>i) f[i][j]=0;
else if(i==j) f[i][j]=1;//特判
else f[i][j]=f[i-1][j-1]+f[i-j][j];//递推式
}
cout<<f[n][k];
return 0;
}