- 1、原创力文档(book118)网站文档一经付费(服务费),不意味着购买了该文档的版权,仅供个人/单位学习、研究之用,不得用于商业用途,未经授权,严禁复制、发行、汇编、翻译或者网络传播等,侵权必究。。
- 2、本站所有内容均由合作方或网友上传,本站不对文档的完整性、权威性及其观点立场正确性做任何保证或承诺!文档内容仅供研究参考,付费前请自行鉴别。如您付费,意味着您自己接受本站规则且自行承担风险,本站不退款、不进行额外附加服务;查看《如何避免下载的几个坑》。如果您已付费下载过本站文档,您可以点击 这里二次下载。
- 3、如文档侵犯商业秘密、侵犯著作权、侵犯人身权等,请点击“版权申诉”(推荐),也可以打举报电话:400-050-0827(电话支持时间:9:00-18:30)。
查看更多
ACM寒假集训--01背包与完全背包 * * 话题引入: 小P同学爱好探险寻宝,一天他去了伊利哇呀半岛发现了一批宝藏,但不幸的是小P很懒,出门只带了一个背包,所以注定他不能带走所有的宝藏。但是小P又很贪心想带走尽量多的宝藏。。。已知每种宝贝的重量与价值是不一样的,小P很笨,没有你聪明,但是聪明的你想到了好的解决方案了吗? * * 数据分析: 假设背包的容量上限为5kg A宝贝 重2kg价值3,000,000,000$ B宝贝 重3kg价值4,000,000,000$ C宝贝 重4KG价值6,500,000,000$ D宝贝 重5KG价值6,700,000,000$ E宝贝 重6KG价值10,000,000,000$ 你认为怎么装才最合理为什么啊? 解题思路? 你是怎么想的啊??? * * 思考贪心和01背包的区别 一般同学们会考录到用贪心的算法通过求最大的性价比来填满背包,大家考录一下这样会有什么样的不妥之处。。。。 贪心与背包的不同: 首先说一下贪心是每一步都是最优的决策,就是每次方我都会放进去解决问题的目前最好的结果。 贪心虽然会带来每一次最优但是不一定是整体最优。(比如说C的性价比最高,但是放了C就不能放别的了,总价值就不如放A和B的多了) 背包可以从宏观上整体得到一个最优的结果。 * * 01背包原理阐述 01背包的原理其实不是很难理解,你不要被他唬住,不要畏惧,其实他也就是那么一回事。。。。 问题的特点是:每种物品一件,可以选择放1或不放0。 用子问题定义状态:即f[i][v]表示前i件物品恰放入一个容量为v的背包可以获得的最大价值。则其状态转移方程便是: f[i][v] = max{f[i-1][v-p[i]] + w[i], f[i-1][v]} 在这里解释一下公式中‘,’号前面是放的状态,后面是不放的状态; 如果在这里第i件物品放的话就表明它是由第i-1的状态传递过来的并且加上新的价值w[i],如果不放就表明这里是保持第i-1的状态没有增加新的价值。 博客链接:/s/blog_6dcd26b301013810.html * * 题目举例:HDU2602 思考一下应该怎么解决? * * 你看懂了吗。。? * * 代码研讨 #include stdio.h #define MAXN 1002 int dp[MAXN][MAXN], w[MAXN], p[MAXN]; int _max(int a, int b){ return a b ? a : b; } int main(){ int n, v, T, i, j; scanf(%d, T); while(T--){ scanf(%d %d, n, v); for(i=1; i=n; i++){ scanf(%d, w[i]); } for(i=1; i=n; i++){ scanf(%d, p[i]); } for(i=0; i=n; i++) dp[i][0] = 0; for(i=0; i=v; i++) dp[0][i] = 0; for(i=1; i=n; i++){ for(j=0; j=v; j++){ dp[i][j] = dp[i-1][j]; if(j=p[i]) dp[i][j] = _max(dp[i-1][j], dp[i-1][j-p[i]]+w[i]); } } printf(%d\n, dp[n][v]); } return 0; } 一维数组的优化 #include stdio.h #include string.h #define MAXN 1002 int max_num(int a, int b){ return a b? a : b; } int dp[MAXN], w[MAXN], p[MAXN]; int main(){ int n, v, T, i, j; scanf(%d, T); while(T--){ scanf(%d %d, n, v); for(i=1; i=n; i++){ scanf(%d, w[i]); } for(i=1; i=n; i++){ scanf(%d, p[i]);
文档评论(0)