太空电梯

奶牛们要去太空了!它们打算用方块建造一座太空电梯。现在它们有 \(N\) 种方块,第 \(i\) 种方块有一个特定的高度 \(h_i\),一定的数量 \(c_i\)。为了防止宇宙射线破坏方块,第 \(i\) 种方块的任何部分不能超过高度 \(a_i\)
请用这些方块堆出最高的太空电梯。

每件物品最多可以\(M\)次,求总价值最大。
\(m\)代表次数,\(j\)代表背包容量,\(val\)代表当前物品的价值

第一种写法

第二层\(for\)循环不能使用正序遍历,并且每个物品的次序遍历要放在第三层for循环。假如正序遍历,当\(j=10\)时,\(m=1 val=2\)的话,那么这一次便给\(dp[j-m*val](dp[10-2]=dp[8])\)赋值,当\(m=2,val=2,j=12\)时,又会给\(dp[8]\)再赋值一次。同理假如\(m\)的循环是第二层结果也是一样,会重复赋值

  ufr(i, 1, n)
      lfr(j, dat[i].a, dat[i].h) 
        for (int k = 1;j >= k * dat[i].h && k <= dat[i].c; ++k)
          dp[j] = max(dp[j], dp[j - k * dat[i].h] + k * dat[i].h);
  f.pt(*max_element(goto(dp, dat[n].a)));

第二种写法

对同一个物品对容量为\(w\)的背包赋值\(m\)

  ufr(i, 1, n)
    ufr(k, 1, dat[i].c)
      lfr(j, dat[i].a, dat[i].h){
         dp[j] = max(dp[j], dp[j - dat[i].h] + dat[i].h);
      }
  f.pt(*max_element(goto(dp, dat[n].a)));

本题的第二种做法

如果第\(i\)件物品堆积,那么如果要保证最大值,那么一定是在第\(i-1\)的基础之上进行堆积,将第\(dp[j-k*val]\)能赋值的位置都设置为\(true\),那么第\(i\)件物品一定是在\(dp[j-k*val]\)基础之上操作

   ufr(i, 1, n) 
     lfr(j, dat[i - 1].a, 0) if (dp[j]) 
        for (int k = 1; k <= dat[i].c && j + k * dat[i].h <= dat[i].a; ++k)
          dp[j + k * dat[i].h] = true;
 lfr(i, dat[n].a, 0)if (dp[i]) f.pt(i).ln();

原文地址:http://www.cnblogs.com/GuanStudy/p/16916845.html

1. 本站所有资源来源于用户上传和网络,如有侵权请邮件联系站长! 2. 分享目的仅供大家学习和交流,请务用于商业用途! 3. 如果你也有好源码或者教程,可以到用户中心发布,分享有积分奖励和额外收入! 4. 本站提供的源码、模板、插件等等其他资源,都不包含技术服务请大家谅解! 5. 如有链接无法下载、失效或广告,请联系管理员处理! 6. 本站资源售价只是赞助,收取费用仅维持本站的日常运营所需! 7. 如遇到加密压缩包,默认解压密码为"gltf",如遇到无法解压的请联系管理员! 8. 因为资源和程序源码均为可复制品,所以不支持任何理由的退款兑现,请斟酌后支付下载 声明:如果标题没有注明"已测试"或者"测试可用"等字样的资源源码均未经过站长测试.特别注意没有标注的源码不保证任何可用性