【动态规划】完全背包:整数划分(方案数)


可以转换为完全背包问题 
从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];

猜你喜欢

转载自blog.csdn.net/m0_52043808/article/details/124001818