数的划分
题目描述
将整数
n
n
n分成
k
k
k份,且每份不能为空,任意两个方案不相同(不考虑顺序)。
例如:
n
=
7
,
k
=
3
n=7,k=3
n=7,k=3,下面三种分法被认为是相同的:
1,1,5; 1,5,1; 1,1,5.
问有多少种不同的分法。
输入格式
两个整数, n n n和 k k k 。
输出格式
输出不同的分法数。
输入样例
7 3
输出样例
4
样例说明
四种分法为:1,1,5; 1,2,4; 1,3,3; 2,2,3.
思路
设
f
(
i
,
j
)
f(i,j)
f(i,j)表示整数
i
i
i分成
j
j
j风的方案数,显然
i
<
j
i<j
i<j时
f
(
i
,
j
)
=
0
f(i,j)=0
f(i,j)=0,
i
=
j
i=j
i=j时
f
(
i
,
j
)
=
1
f(i,j)=1
f(i,j)=1。
其他的状态我们考虑两种情况:
1、
j
j
j份中至少要有一份为1,显然方案书为
f
(
i
−
1
,
j
−
1
)
f(i-1,j-1)
f(i−1,j−1)。
2、
j
j
j份中一份1都没有,我们考虑先将
i
−
j
i-j
i−j分成
j
j
j份,再往
j
j
j份中的每一份加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;
}