雖說是DP入門題,但第一次要理解還是會花很大的勁。
dp[i][j]表示j塊蛋糕放在i個盤子上的方法數,可有盤子是空的。
①若i==j
當盤子有空,問題可轉化爲dp[i-1][j] (i-1保證了至少有一個盤子是空);
當盤子全滿,只有一種情況,就是每個盤子放一塊蛋糕;
②若i>j
當盤子有空,問題轉化爲dp[i-1][j];
不存在盤子滿的狀態;
③若i<j
當盤子有空,問題轉化爲dp[i-1][j]
當盤子全滿,每個盤子放一個蛋糕保證盤子全滿,然後問題轉化爲j-i塊蛋糕放入i個盤子的問題,即dp[i][j-i]。
#include <iostream>
using namespace std;
#define N 4505
int dp[N][N];
int main()
{
int n, m;
scanf("%d%d",&n,&m);
for(int i=0; i<=m; i++)
dp[1][i] = 1;
for(int i=2; i<=n; i++)
for(int j=1; j<=m; j++)
{
if(i==j)
dp[i][j] = dp[i-1][j] + 1;
else if(i<j)
dp[i][j] = dp[i-1][j] + dp[i][j-i];
else
dp[i][j] = dp[i-1][j];
if(dp[i][j]>1000000007)
dp[i][j]-=1000000007;
}
printf("%d\n",dp[n][m]);
return 0;
}