可以转换为完全背包问题
从1~n选择若干个数,使它们的和恰好为n,一共有多少种方案
dp[i][j]表示从前i个数选若干个数,使它们的和恰好为j的方案数
考虑第i个数选几次
dp[i][j]=dp[i-1][j]+dp[i-1][j-i]+dp[i-1][j-2*i]+...
时间优化:
注意到 dp[i][j-i]=dp[i-1][j-i]+dp[i-1][j-2*i]+dp[i-1][j-3*i]+....
所以dp[i][j]=dp[i-1][j]+dp[i][j-i]
空间优化:
滚动数组
for i 1~n:
for j i~n: dp[j]=dp[j]+dp[j-i]
代码:
int n;
cin>>n;
memset(dp,0,sizeof(dp));
dp[0]=1;
for(int i=1;i<=n;i++)
{
for(int j=i;j<=n;j++)
{
dp[j]=(dp[j]+dp[j-i])%mod;
}
}
cout<<dp[n];