lintcode-92-背包问题
92-背包问题
在n个物品中挑选若干物品装入背包,最多能装多满?假设背包的大小为m,每个物品的大小为A[i]
注意事项
你不可以将物品进行切割。
样例
如果有4个物品[2, 3, 5, 7]
如果背包的大小为11,可以选择[2, 3, 5]装入背包,最多可以装满10的空间。
如果背包的大小为12,可以选择[2, 3, 7]装入背包,最多可以装满12的空间。
函数需要返回最多能装满的空间大小。挑战
O(n x m) time and O(m) memory.
O(n x m) memory is also acceptable if you do not know how to optimize memory.标签
动态规划 背包问题 LintCode 版权所有
方法一(空间复杂度O(n x m) )
使用二维数组 dp[i][j] 记录前 i 个数,在背包大小为 j 的条件下,最多可以装满的空间
在仅有一个物品元素时,最多可装满的空间就是此物品大小(前提是背包可以装下此物品)
有多个元素时,要装入一个新元素,则最多可以装满的空间就是装入此元素前,背包大小为当前背包大小-此元素大小的大小+此元素的大小(装入新元素),或不变(未能装下此元素)
也可以解释为:
不放第i个物品:dp[i-1][j]
放第i个物品:那么问题就转化为“前i-1件物品放入剩下的容量为j-A[i]的背包中”,此时能获得的最大体积就是dp[i-1][j-A[i]]再加上通过放入第i件物品获得的体积A[i]
转自http://www.cnblogs.com/theskulls/p/5487061.html
具体过程如下图所示:

状态转移方程为:dp[i][j] = max(dp[i - 1][j - A[i]] + A[i], dp[i - 1][j])
code
class Solution {
public:
/**
* http://www.lintcode.com/zh-cn/problem/backpack/-92-背包问题
* @param m: An integer m denotes the size of a backpack
* @param A: Given n items with size A[i]
* @return: The maximum size
*/
int backPack(int m, vector<int> A) {
// write your code here
int size = A.size(), i = 0, j = 0;
if(size <= 0) {
return 0;
}
sort(A.begin(), A.end());
vector< vector<int> > dp(size, vector<int>(m+1, 0) );
for(i=0; i<size; i++) {
for(j=1; j<=m; j++) {
if(i==0 && j>=A[i]) {
dp[i][j] = A[i];
}
else if(i>0 && j>=A[i]){
dp[i][j] = (dp[i-1][j-A[i]] + A[i] > dp[i-1][j]) ? dp[i-1][j-A[i]] + A[i] : dp[i-1][j];
}
else if(i>0 && j<A[i]){
dp[i][j] = dp[i-1][j];
}
}
}
return dp[size-1][m];
}
};
方法二(空间复杂度 O(m) )
优化方法一的状态方程,使用一维数组 dp[i] 记录所有物品在背包大小为 j 的条件下,最多可以装满的空间
在方法一中,二维数组的每一行仅仅与其上一行相关,所以可以将二维数组压缩成一维数组,可以相成用二维数组的下一行将上一行覆盖
因为新的结果要与其在二维素组中左上位置的元素比较(即一维数组中左边的元素比较),所以从后向前遍历一维数组,并写入新元素
状态转移方程为:dp[j] = max(dp[j], dp[j - A[i]] + A[i])
code
class Solution {
public:
/**
* @param m: An integer m denotes the size of a backpack
* @param A: Given n items with size A[i]
* @return: The maximum size
*/
int backPack(int m, vector<int> A) {
// write your code here
int size = A.size(), i = 0, j = 0;
if(size <= 0) {
return 0;
}
int *dp = new int[m+1];
for(i=0; i<m+1; i++) {
dp[i] = 0;
}
for(i=0; i<size; i++) {
for(j=m; j>=1; j--) {
if(j >= A[i]) {
dp[j] = (dp[j]>dp[j-A[i]] + A[i])?dp[j]:dp[j-A[i]] + A[i];
}
}
}
return dp[m];
}
};
lintcode-92-背包问题的更多相关文章
- 92.背包问题(lintcode)
注意j-A[i-1]必须大于等于0,只大于0会报错 class Solution { public: /** * @param m: An integer m denotes the size of ...
- lintcode:背包问题II
背包问题II 给出n个物品的体积A[i]和其价值V[i],将他们装入一个大小为m的背包,最多能装入的总价值有多大? 注意事项 A[i], V[i], n, m均为整数.你不能将物品进行切分.你所挑选的 ...
- lintcode:背包问题
背包问题 在n个物品中挑选若干物品装入背包,最多能装多满?假设背包的大小为m,每个物品的大小为A[i] 样例 如果有4个物品[2, 3, 5, 7] 如果背包的大小为,可以选择的空间. 如果背包的大小 ...
- leetcode刷题全纪录(持续更新)
2.Add Two Numbers 原题链接https://leetcode.com/problems/add-two-numbers/ AC解: public ListNode addTwoNumb ...
- 动态规划算法模板和demo
366. 斐波纳契数列 中文 English 查找斐波纳契数列中第 N 个数. 所谓的斐波纳契数列是指: 前2个数是 0 和 1 . 第 i 个数是第 i-1 个数和第i-2 个数的和. 斐波纳契数列 ...
- LeetCode入门指南 之 动态规划思想
推荐学习labuladong大佬的动态规划系列文章:先弄明白什么是动态规划即可,不必一次看完.接着尝试自己做,没有思路了再回过头看相应的文章. 动态规划一般可以由 递归 + 备忘录 一步步转换而来,不 ...
- 背包问题2 (lintcode)
这里: for(int j = 1;j <= m;j++) result[0][j] = 0x80000000; 不能从0开始,result[0][0]是可以取到的,是0.其他情况取不到才用最小 ...
- leetcode & lintcode for bug-free
刷题备忘录,for bug-free leetcode 396. Rotate Function 题意: Given an array of integers A and let n to be it ...
- leetcode & lintcode 题解
刷题备忘录,for bug-free 招行面试题--求无序数组最长连续序列的长度,这里连续指的是值连续--间隔为1,并不是数值的位置连续 问题: 给出一个未排序的整数数组,找出最长的连续元素序列的长度 ...
- [LintCode]——目录
Yet Another Source Code for LintCode Current Status : 232AC / 289ALL in Language C++, Up to date (20 ...
随机推荐
- 冒泡排序_C语言_数组
冒泡排序_C语言_数组 #include <stdio.h> //冒泡排序 小->大 void sort(int * pArray, int len); int main(int a ...
- iOS 让视图UIView单独显示某一侧的边框线
iOS 让视图UIView 单独显示某一侧的边框线 有时候需要让view显示某一侧的边框线,这时设置layer的border是达不到效果的.在网上查阅资料发现有一个投机取巧的办法,原理是给view ...
- PTA Java tips(转载)
在PTA提交Java程序需要注意如下几个要点 1. Main类与Scanner 1.1 Main类 你提交的所有程序都应该以如下形式出现 public class Main{ public stati ...
- 【TOJ 5103】Electric Fence(皮克定理)
描述 In this problem, `lattice points' in the plane are points with integer coordinates. In order to c ...
- 23种java设计模式之装饰者模式及动态代理
设计模式不管对于何种语言都是存在的,这里介绍的是java的模式 装饰者模式是在二次开发中应用比较多的一款模式,当然了用反射也是可以实现的,今天介绍的是装饰模式,有兴趣的朋友可以自己去了解一下反射是怎么 ...
- 在Liunx上搭建FTP并配置用户权限
伴随着.Net Core的开源,公司前几天上了新的Liunx服务器,我在前几篇文章中介绍了如何搭建环境以及部署.Net Core应用. 然后,今天客户和我说想自己给网站做推广,需要用FTP链接我们的服 ...
- 继上一篇bootstrap框架(首页)弄的资讯页面
还是和上一篇首页一样给出每一步的注解: 做的有点简单,但是,以后还是会加深的.毕竟是初学者嘛! <html lang="zh-cn"> <head> ...
- angularjs路由不断刷新当前页面
最近做项目遇到个问题,使用angular-route的时候,第一次点击 [按钮 a]会进入按钮a对应的控制器,接着再次点击a按钮的的时候就不会进入控制器了.我想要的效果是每次点击都能进入control ...
- python3 练习题100例 (二十八)打印一定范围内的素数
题目内容: 给定一个大于2的正整数n,打印出小于n(不包括n且n不大于100)的所有素数. 要求将符合条件的输出填入一个列表中,打印的结果为该列表. 输入格式: 共一行,为一个大于2的正整数 输出格式 ...
- c/c++指针理解
指针的概念 指针是一个特殊的变量,它里面存储的数值被解释成为内存里的一个地址.要搞清一个指针需要搞清指针的四方面的内容:指针的类型,指针所指向的类型,指针的值或者叫指针所指向的内存区,还有指针本身所占 ...