【LintCode】Backpack 背包问题
2015-07-16 12:52
274 查看
在n个物品中挑选若干物品装入背包,最多能装多满?假设背包的大小为m,每个物品的大小为A[i]。
样例
如果有4个物品[2, 3, 5, 7]
如果背包的大小为11,可以选择[2, 3, 5]装入背包,最多可以装满10的空间。
如果背包的大小为12,可以选择[2, 3, 7]装入背包,最多可以装满12的空间。
函数需要返回最多能装满的空间大小。
注意
你不可以将物品进行切割。
举例:
如果有4个物品[2, 3, 5, 7],如果背包的大小为11。问最多能装多满?
建动态规划数组 dp[A.length][m + 1],A.length行,m+1列
dp[i][j]为当背包总重量为j且有前i个物品时,背包最多装满dp[i][j]的空间。
状态转移方程为:dp[i][j] = Math.max(dp[i - 1][j - A[i]] + A[i], dp[i-1][j]);
dp[i - 1][j - A[i]] + A[i]为加入第i个物品后背包的总装满空间。
a.为了把第i个物品放进背包,背包当然要先腾出至少A[i]的空间,腾出后空间的最多装满空间为dp[ i - 1][j - A[i]],再加上第i个物品的空间A[i],即为当背包总空间为j时,装入第i个物品背包的总装满空间。
b.当然第i个物品所占的空间可能比此时背包的总空间j要大(j < A[i]),此时装不进第i个物品,因此此时背包的总装满空间为dp[i-1][j]。
c.还有一种可能的情形是,虽然第i个物品能够装入包中,但为了把第i个物品装入而拿出了其他物品,使此时的总装入空间dp[i-1][j-A[i]] + A[i] < dp[i-1][j]
其他情形:
当j = 0时,dp[i][0] = 0
原题答案即为dp[3][11] = 10,背包的总空间为11时,四个物品能够装入的最大空间为多大。
样例
如果有4个物品[2, 3, 5, 7]
如果背包的大小为11,可以选择[2, 3, 5]装入背包,最多可以装满10的空间。
如果背包的大小为12,可以选择[2, 3, 7]装入背包,最多可以装满12的空间。
函数需要返回最多能装满的空间大小。
注意
你不可以将物品进行切割。
举例:
如果有4个物品[2, 3, 5, 7],如果背包的大小为11。问最多能装多满?
建动态规划数组 dp[A.length][m + 1],A.length行,m+1列
start | j = 0 | j = 1 | j = 2 | j = 3 | j = 4 | j = 5 | j = 6 | j = 7 | j = 8 | j = 9 | j = 10 | j = 11 |
---|---|---|---|---|---|---|---|---|---|---|---|---|
i = 0 (A[0]=2) | dp[0][0] = 0 | 0 | 2 | 2 | 2 | 2 | 2 | 2 | 2 | 2 | 2 | 2 |
i = 1 (A[1]=3) | 0 | 0 | 2 | 3 | 3 | 5 | 5 | 5 | 5 | 5 | 5 | 5 |
i = 2 (A[2]=5) | 0 | 0 | 2 | 3 | 3 | 5 | 5 | 7 | 8 | 8 | 10 | 10 |
i = 3 (A[3]=7) | 0 | 0 | 2 | 3 | 3 | 5 | 5 | 7 | 8 | 10 | 10 | 10 |
状态转移方程为:dp[i][j] = Math.max(dp[i - 1][j - A[i]] + A[i], dp[i-1][j]);
dp[i - 1][j - A[i]] + A[i]为加入第i个物品后背包的总装满空间。
a.为了把第i个物品放进背包,背包当然要先腾出至少A[i]的空间,腾出后空间的最多装满空间为dp[ i - 1][j - A[i]],再加上第i个物品的空间A[i],即为当背包总空间为j时,装入第i个物品背包的总装满空间。
b.当然第i个物品所占的空间可能比此时背包的总空间j要大(j < A[i]),此时装不进第i个物品,因此此时背包的总装满空间为dp[i-1][j]。
c.还有一种可能的情形是,虽然第i个物品能够装入包中,但为了把第i个物品装入而拿出了其他物品,使此时的总装入空间dp[i-1][j-A[i]] + A[i] < dp[i-1][j]
其他情形:
当j = 0时,dp[i][0] = 0
原题答案即为dp[3][11] = 10,背包的总空间为11时,四个物品能够装入的最大空间为多大。
public class Solution { /** * @param m: An integer m denotes the size of a backpack * @param A: Given n items with size A[i] * @return: The maximum size */ public int backPack(int m, int[] A) { int[][] dp = new int[A.length][m + 1];//动态规划矩阵 for(int i = 0; i < A.length; i ++) {//背包空间为0时,不管要放第几个物品,可装满的背包空间为0. dp[i][0] = 0; } for(int j = 1; j < m + 1; j++) { if(A[0] <= j) {//当第0个物品的空间小于等于当前背包空间j时 dp[0][j] = A[0];//背包可装满的最大空间是第0个物品的体积 }else {//当第0个物品的空间大于当前背包空间j时 dp[0][j] = 0;//背包可装满的最大空间是0 } for(int i = 1; i < A.length; i++) {//当放第1个到第A.length-1个物品时 if(A[i] > j) {//若该物品所占空间大于背包总空间(无论怎样腾背包空间,该物品无法放入背包 dp[i][j] = dp[i - 1][j];//背包可装满的最大空间不变 }else {//若该物品所占空间小于等于背包总空间,则需将背包空间腾出至少A[i]后,将该物品放入。放入新物品后背包最大可装满空间可能更大,也可能变小大,取大值作为背包空间为j且放第i个物品时可以有的最大可装满空间。 dp[i][j] = Math.max(dp[i-1][j - A[i]] + A[i], dp[i - 1][j]); } } } return dp[A.length - 1][m]; } }
相关文章推荐
- 01-Jvm 内存区域复习笔记
- POJ1229 域名匹配
- 01-Jvm 内存区域复习笔记 分类: JVM Java 2015-07-16 12:52 139人阅读 评论(0) 收藏
- mysql中间件研究(Atlas,cobar,TDDL)
- hibernate ORM的作用
- 想越狱的小衫
- 搞笑的<Button></Button>
- 引用形参使用中要注意的问题
- 顺序表查找之二分查找
- C++ 中string.find() 函数的用法总结
- CUDA Thrust 规约求和
- 刷机包各个文件都是啥
- Servlet&JSP思维导图
- 刷机包各个文件都是啥
- hibernate缓存一级和二级的区别
- mysql分表的3种方法
- ComboxEdit实现二级联动
- Mysql分库分表方案
- 关于GA-6UASL3(Rev:2.1)主板安装Windows2003蓝屏(代码:STOP: 0x0000007B...)问题
- mac常用快捷方式