基础01背包问题
概述
给出一个容积为V的背包,有i个物体,每个物体都有自己的体积和价值,用Vi和Wi表示,要将这些物体装进背包里面,问怎样才能使得装入物体的总价值最大?最大为多少?
解决思路
1.如果你没能正确理解这道题,尤其是对于很多新手,第一反应可能是将所有物体的单位价值算出来,然后按从大到小排序,将单位价值高的物体优先放入背包······
我们来举个例子:现在你的背包体积为10,现在有4个物体,体积分别为1,3,5,7,价值分别为1,4,15,18;如果按单位价值来算15/5>18/7>4/3>1/1,所以现将体积为5的物体放入背包,那么接下来就只能依次放入体积为3和1的物体,这样的话总价值为20,但是显然放入体积为7和3的物体,总价值为22是最大的,那么这种放的方式怎么用算法表示出来呢?
2.算法思路:根据动态规划解题步骤(问题抽象,建立模型,寻找约束条件,判断是否满足最优解原理,找大问题与小问题的递推关系式,填表,寻找解组成)找出01背包问题的最优解及解组成,然后编写代码实现。动态规划其实就是把大问题拆解成一个个的小问题,通过寻找大问题与小问题的递推关系,解决一个个的小问题,最终达到解决大问题的效果,且动态规划的优点在于填表(具有记忆性),可以理解成表中记录每个局部最优然后最终得到全局最优。
3.什么是填表:就是依次将背包容积从1开始递增,记录每一个容积下的最优解,然后通过该最优解推导下一个容积的最优解。这就涉及到一个嵌套循坏了,不仅要将体积从1开始递增,还需要将物体从第一个开始递增,即:将第一次循环只考虑第一个物体,遍历所有的容积,天第一行表,第二次循环考虑前两个物体,遍历所有体积,填第二行表·····(有多少个物体就填多少行表,一共有背包的总容积V列 ,每一行都从体积为1开始填一直到体积为V)
4.大问题与小问题的递推关系式:若有n个物体,背包总容积为m,由上述分析可知这个表应该为n*m(实际上要为(n+1)*(m+1)因为要初始化边缘行列为0),用dp[i][j]来表示该表的第i行第j列(表示考虑放前i个物体且背包容量为j时的最大放入价值)
对于每一个dp[i][j]每次就只需要考虑两种情况:
①背包体积不够放入第i个物体,则dp[i][j]=dp[i-1][j];
②背包体积足够放入第i个物体,但是放入之后剩余体积就变小了,所以需要联系上一行体积相同时的最大价值再加上i的价值和dp[i-1][j]进行比较,
即:dp[i][j]=max(dp[i-1][j],dp[i-1][j-Vi]+Wi)
5.最优解回溯:
①dp[i][j]=dp[i-1][j]时,说明没有选择第i个物体,则回到dp[i-1][j];
②dp[i][j]=dp[i-1][j-Vi]+Wi时,说明选择了第i个物体,该物体是最优解的组成部分,随后我们回到选择该物体之前,即dp[i-1][j-Vi];
③一直遍历到i=0结束为止,所有组成的解都会被找到
例题1:Ieee全球极限编程大赛11.0题BeetleBag
题目:
Beetleman joined the Strangers, a t

最低0.47元/天 解锁文章
879

被折叠的 条评论
为什么被折叠?



