算法——动态规划篇——01背包问题
2014-05-17 15:06
351 查看
问题描述:给定n种物品和一背包,物品i的重量是wi,其价值是pi,背包的容量是M,问如何选择装入背包中的物品总价值最大?
比如说,现在有一个背包,容量上限是10,可以放物品的个数为3,即m=10,n=3;
物品的容量和价值分别为:
3,4
4, 5
5,6
考虑怎么做,可以从这三件物品中选出价值最大的东西来进行组合呢。
直观上可以看出,就是后两种组合到一起,问题的关键是如何让计算机知道,来分析这个过程
动态规划的思想:空间换时间
观察上面的表
这也是一个二维数组total[4][11];
扩大了数组的范围,用来填充下标为0的情况。。
分析:
我们考虑从三个物品中任选一个物品开始讨论,假设按顺序放,开始情况为total[1][1];表示在容量为1的情况下放1个物品,怎么放呢,由于第一物品的容量为3>1,无法放进去,所以total[1][1]的值应该沿着在容量为1放0个物品的情况下的值过来,即total[1][1]=total[0][1]=0;
同理total[1][2]=0,
那么total[1][3]呢,total[1][3]的容量为3,第一个物品对应的容量也刚好为3,所以理论上是可以将物品1放到背包里面,但是,还需要考虑的是,万一total[0][3]的价值比物品1的价值大呢,(这个地方,total[0][3]=0,只是用来说明有这种情况),
我们换一种情况来说明;
total[3][6],物品3的容量为5,小于6,可以将物品3放入到背包中,该不该放入呢,我们需要知道total[2][6]的值,为5。如果将物品3放入的话,那么容量只剩下6-5=1的容量了,原来是要放入2件物品的,即是total[2][1],有前面的表知道它为0。总的来说就是要判断total[2][6],跟total[2][1]+物品3的价值,他们两者中的大的一个,作为total[3][6]的值。
大致的思路就是这样的,具体还需要自己体会。。。
代码如下:
结果如下,去掉了下标为0的记录:
0
0 4 4 4 4 4 4 4 4
0 0 4 5 5 5 9 9 9 9
0 0 4 5 6 6 9 10 11 11
动态规划的思想就是将每一步计算的值保留下来,留作以后使用,空间换时间,还需要不断的去体会。
比如说,现在有一个背包,容量上限是10,可以放物品的个数为3,即m=10,n=3;
物品的容量和价值分别为:
3,4
4, 5
5,6
考虑怎么做,可以从这三件物品中选出价值最大的东西来进行组合呢。
直观上可以看出,就是后两种组合到一起,问题的关键是如何让计算机知道,来分析这个过程
动态规划的思想:空间换时间
0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 |
0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
0 | 0 | 0 | 4 | 4 | 4 | 4 | 4 | 4 | 4 | 4 |
0 | 0 | 0 | 4 | 5 | 5 | 5 | 9 | 9 | 9 | 9 |
0 | 0 | 0 | 4 | 5 | 6 | 6 | 9 | 10 | 11 | 11 |
这也是一个二维数组total[4][11];
扩大了数组的范围,用来填充下标为0的情况。。
分析:
我们考虑从三个物品中任选一个物品开始讨论,假设按顺序放,开始情况为total[1][1];表示在容量为1的情况下放1个物品,怎么放呢,由于第一物品的容量为3>1,无法放进去,所以total[1][1]的值应该沿着在容量为1放0个物品的情况下的值过来,即total[1][1]=total[0][1]=0;
同理total[1][2]=0,
那么total[1][3]呢,total[1][3]的容量为3,第一个物品对应的容量也刚好为3,所以理论上是可以将物品1放到背包里面,但是,还需要考虑的是,万一total[0][3]的价值比物品1的价值大呢,(这个地方,total[0][3]=0,只是用来说明有这种情况),
我们换一种情况来说明;
total[3][6],物品3的容量为5,小于6,可以将物品3放入到背包中,该不该放入呢,我们需要知道total[2][6]的值,为5。如果将物品3放入的话,那么容量只剩下6-5=1的容量了,原来是要放入2件物品的,即是total[2][1],有前面的表知道它为0。总的来说就是要判断total[2][6],跟total[2][1]+物品3的价值,他们两者中的大的一个,作为total[3][6]的值。
大致的思路就是这样的,具体还需要自己体会。。。
代码如下:
package hello.ant; public class AlogBeiBao { //动态规划 public static void main(String[] args) { int m=10,count=3; int capacity[]={3,4,5}; int value[]={4,5,6}; int total[][]=new int[count+1][m+1]; int i; //初始化 for(i=0;i<m+1;i++){ total[0][i]=0; } for(i=0;i<count+1;i++){ total[i][0]=0; } for(i=1;i<count+1;i++){ for(int j=1;j<m+1;j++){ if(j>=capacity[i-1]){ total[i][j]=max(total[i-1][j],total[i-1][j-capacity[i-1]]+value[i-1]); }else { total[i][j]=total[i-1][j]; } System.out.print(total[i][j]+" "); } System.out.println(); } } static int max(int i, int j) { if(i>=j){ return i; } return j; } }
结果如下,去掉了下标为0的记录:
0
0 4 4 4 4 4 4 4 4
0 0 4 5 5 5 9 9 9 9
0 0 4 5 6 6 9 10 11 11
动态规划的思想就是将每一步计算的值保留下来,留作以后使用,空间换时间,还需要不断的去体会。
相关文章推荐
- 回溯算法---01背包问题
- 【算法】01背包问题的Java实现
- [算法]01背包问题
- 【算法笔记】贪心算法——01背包问题
- 每天一道算法题(四) (动态规划算法)01背包问题Java实现
- 01背包问题 原理 算法
- 【01背包问题】:动态规划、回溯法和分支限界法 三种算法的对比与分析(时间复杂度方面)
- 遗传算法解01背包问题(Java)
- 算法学习 - 01背包问题(动态规划C++)
- 算法面试---01背包问题---动态规划
- [转][算法]01背包问题
- 01背包问题算法解释与C代码实现
- 算法导论三剑客之 动态规划 01背包问题
- 【算法】动态规划的用法——01背包问题
- 每日学习一算法【4】01背包问题
- 回溯算法-01背包问题
- 算法——动态规划篇——采药问题
- 算法基础-动态规划 (1) 01背包问题
- 算法_动态规划_01背包问题(重量为浮点型)
- 基础算法 01背包问题