做到了一个题,发现对背包问题理解有点浅,应该说是忘了
Dutch Democracy
给你一个数集,你要找到出满足以下两个条件的子集的个数
1.和大于所有的一半
2.去掉任意一个就比一半小了
其实就是一个背包问题
先排序
对于每一个物品,加进去之后会贡献答案的范围是【max(0,sum/2-p[i]),sum/2】,所以加上这区间内dp数组的答案
然后更新dp[j]
记得倒序更新,否则一个答案会被计算多次
Bottle
给你n瓶水,每瓶水有ai,容量为bi,水可以转移,一个单位转移消耗一秒,请你计算将水装到最少瓶子中所需的最小时间
设状态dp[i][j]为装在i瓶水里总容量为j的价值(已有水量)是多少
这样转移就简单了
dp[i][j]=max(dp[i][j],dp[i-1][j-bi]+ai);
然后去求j大于sum的情况下,最大价值是多少
最后答案就是sum-max(dp[t][i])
垃圾陷阱
初始有生命值10,ti时间会投下垃圾,可以选择堆稿hi,也可以增加fi的生命,问最快出去的时间
考虑用f[i][j]表示在前i个垃圾,j高度下的最大生命值
如果当前生命值小于间隔时间delta,撑不住,直接暴毙,continue循环,这个状态不会再被转移
若大于等于
则状态转移
若加上这个已经比D大,输出时间
不然
吃 f[i][j]=max(f[i-1][j]+fi-delta,f[i][j])
堆 f[i][j+hi]=max(f[i][j+hi],f[i-1][j]-delta)
这样无后效性
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/944687.shtml
如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!