2022.3.20
洛谷P1025
将整数 n 分成 k 份,且每份不能为空,任意两个方案不相同(不考虑顺序)。
例如:n=7,k=3,下面三种分法被认为是相同的。
1,1,5;
1,5,1;
5,1,1.
问有多少种不同的分法。
状态转移方程是难点。
首先,dp[i][j]代表i被分j份的方案数。其中易知i<j的时候为0,j=1与i=j的时候为1,为了保险,dp[i][0]也初始化成1。
其他时候,可以分为两种情况,分的份数中有1和没有1。有1时值为dp[i-1][j-1];没有1时为dp[i-j][j];关于第二个怎么理解,可以看作就是将i个球分到j个盒子里
先往每个盒子里放一个,再往剩下的盒子中分剩余的i-j个,如果i-j<j,就为0(因定义在全局变量中,已经初始化为0了),
反之则有一定方案可以满足。故dp[i][j]=dp[i-1][j-1]+dp[i-j][j]。
#include<cstdio>
#include<algorithm>
using namespace std;
int dp[210][10];
int main()
{
int n,k;
scanf("%d%d",&n,&k);
int i,j;
for(i=1;i<=n;i++)
{
dp[i][i]=1;
dp[i][1]=1;
dp[i][0]=1;
}
for(i=2;i<=n;i++)
{
for(j=2;j<=k;j++)
{
if(i>j)
dp[i][j]=dp[i-1][j-1]+dp[i-j][j];
else
dp[i][j]=dp[i-1][j-1];
}
}
printf("%d\n",dp[n][k]);
return 0;
}