对于没有接触过背包的初学者来说,想出这道题的动态规划算法很困难。
纠结了我很长时间,何必说是我的智商问题呢?有些东西可以遮掩,然而做题就要把一个点弄得透彻,正如某句话,理解越深,达到的高度越高。(非原话)
现在论述一下我的看法:
1.对于某个数字,它的拆分方案数,可以分成两部分组成。
假设数字为i,其和为sum,sum=(i+1)*i/4,它的前一数字是i-1,i-1个数字挑选出和为sum的有dp【i-1】【sum】种。和为sum-i的有dp【i-1】【sum-i】种
这两种加起来就是i个数字和为sum的种类数。
dp【i】【sum】=dp【i-1】【sum】+dp【i-1】【sum-i】
换句话讲,动态规划通过扩大空间找出了求出最后结果的一种快速方法。
它的转移方程形式多变。
2,对于这道题而言,空间复杂度仍然较高
由于本题动态规划的数组构建只依赖于上一层的数组,只需*改变构建顺序*,就可以简化数据结构。
请体会下面两组代码
scanf("%d",&n);
int i,j;
dp[1]=1;dp[0]=0;
for(i=1;i<=n;i++)
{for(j=n*(n+1)/4;j>i;j--)
dp[j]=dp[j]+dp[j-i];
}
和
ans[1][1] = 1;
for(int i = 2; i <= n; i++)
for(int j = i+1; j <= half; j++)
ans[i][j] = ans[i-1][j] + ans[i-1][j-i];