问题链接:1039数的划分
题目描述 Description
将整数n分成k份,且每份不能为空,任意两种划分方案不能相同(不考虑顺序)。
例如:n=7,k=3,下面三种划分方案被认为是相同的。
1 1 5
1 5 1
5 1 1
问有多少种不同的分法。
输入描述 Input Description
输入:n,k (6<n<=200,2<=k<=6)
输出描述 Output Description
输出:一个整数,即不同的分法。
样例输入 Sample Input
7 3
样例输出 Sample Output
4
问题分析:与放苹果的题类似
f[i][j]表示数i被分为j份,共有两种情况,一种是不含1的,一种是含有1的。
不含1的可看作是每一份都减去1,共减去j,情况不变,即f[i-j][j];
含有1的可看作是数i-1被分为j-1份,即第j份为1,也就是f[i-1][j-1];
即f[i][j]=f[i-j][j]+f[i-1][j-1]。
#include <iostream>
using namespace std;
ac
f[i][j]=f[i-1][j-1]+f[i-j][j]
分两种情况:全都不是1+至少有一个为1
int f[250][10];
int main()
{
int n,k;
cin>>n>>k;
for(int i=1;i<=n;i++)
{
f[i][1]=1;
}
for(int i=2;i<=n;i++)
{
for(int j=2;j<=k;j++)
{
if(j<=i)
{
f[i][j]=f[i-1][j-1]+f[i-j][j];
}
}
}
cout<<f[n][k]<<endl;
return 0;
}
动态规划想不到的话,还可以用深搜写,因为本题数据量较小。具体分析见注释。
#include <iostream>
using namespace std;
///ac
int dfs(int n,int k,int i)//n个数被分为k份,每份至少为i
{
int sum=0;
if(k==1)//只能被分为1份时,只有一种情况
{
sum++;
return sum;
}
else
{
for(int j=i;j<=n/k;j++)//递增设置最少放置个数,防止重复
{
if(n-j>k-1)
{
sum+=dfs(n-j,k-1,j);
}
}
return sum;
}
}
int main()
{
int n,k;
cin>>n>>k;
int s=dfs(n,k,1);
cout<<s<<endl;
return 0;
}