usaco Subset Sums

对于没有接触过背包的初学者来说,想出这道题的动态规划算法很困难。

纠结了我很长时间,何必说是我的智商问题呢?有些东西可以遮掩,然而做题就要把一个点弄得透彻,正如某句话,理解越深,达到的高度越高。(非原话)

现在论述一下我的看法:

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]; 




  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值