背包问题

简单DP的小见解(入门背包)

我怕爱的太早我们不能终老 提交于 2019-12-25 00:32:48
简单DP的小见解(入门背包) n为个数,m为大小,v[]为单个物品体积,w[]为此物品的价值 01背包(每种物品只能选0件或者1件) 引例:假设小偷去珠宝店盗窃,他的背包容量为C=10,珠宝店里有3件珠宝可以盗窃,问可以装入背包的最大价值是多少。 想要求装入背包的最大价值,肯定要在尽量装满背包的情况下拿走价值尽可能高的物品,使得最后的总价值最大化 dp[n] [m]为第n件物品剩余m空间 第i件物品是否可以拿,存在两种情况: (1)剩余空间不能装下此物品,那么问题转化为将前i-1件物品放入背包中所获得的最大价值.。 (2)剩余空间可以装下此物品,想要求i件物品最优解,对于此物品又面临拿与不拿两种情况: ​ a.拿走此物品,此时的价值就应该是(i-1)件物品时的最优解加上此物品的价值。相应的,因为拿走了这件物 品,空间也会对应减少,此时的状态即:dp[i-1] [j-space[i]]+val[i] ​ b.不拿此物品,此时的价值就应该与拿走前(i-1)件物品获得的最大价值相同,虽然没有拿走这个物品,但是空间也没有减少,这意味着剩下的空间还可以装别的东西。此时状态为:dp[i-1] [j] 得出判断条件 (二维数组) if(j<space[i]) //剩余空间小于该物品体积 dp[i][j]=dp[i-1][j]; else dp[i][j]=max(dp[i-1][j],dp[i

01背包、完全背包、多重背包

亡梦爱人 提交于 2019-12-24 07:03:26
参考(都有些错误):https://github.com/guanjunjian/Interview-Summary/blob/master/notes/algorithms/%E7%BB%8F%E5%85%B8%E7%AE%97%E6%B3%95/01%E8%83%8C%E5%8C%85.mdhttps://blog.csdn.net/na_beginning/article/details/62884939 #include <iostream> #include <sstream> #include <vector> #include <string> using namespace std; /* 01背包问题 每个物品仅一个 状态转移公式:F[i][j] = F[i - 1][j] 和 F[i - 1][j - W[i]] + V[i] 大的那个值 C背包总重量 W每个物品重量 V每个物品价值 n物品总数 inp具有最大价值时,标记哪个物品在包中 返回最大价值 */ int packages(int C, vector<int> &W, vector<int> &V, int n, vector<int> &inp) { vector<vector<int> > F(n, vector<int>(C + 1));//F[i][j]记录背包可用重量为j时

背包问题

狂风中的少年 提交于 2019-12-24 00:25:20
检验代码 背包九讲 0-1背包 有 N 件物品和一个容量是 V 的背包。每件物品只能使用一次。 第 i 件物品的体积是 vi,价值是 wi。 求解将哪些物品装入背包,可使这些物品的总体积不超过背包容量,且总价值最大。 输出最大价值。 输入格式 第一行两个整数,N,V用空格隔开,分别表示物品数量和背包容积。 接下来有 N 行,每行两个整数 vi,wi,用空格隔开,分别表示第 i 件物品的体积和价值。 输出格式 输出一个整数,表示最大价值。 数据范围 0<N,V≤1000 0<vi,wi≤1000 输入样例 4 5 1 2 2 4 3 4 4 5 输出样例: 8 CODE: # include <iostream> # include <algorithm> # include <cstring> using namespace std ; const int N = 1010 ; int f [ N ] [ N ] ; int v [ N ] , w [ N ] ; int main ( ) { int n , m ; cin >> n >> m ; int i , j ; for ( i = 1 ; i <= n ; i ++ ) cin >> v [ i ] >> w [ i ] ; for ( i = 1 ; i <= n ; i ++ ) { for ( j = 0 ; j

背包问题学习笔记(一)

拥有回忆 提交于 2019-12-23 16:05:34
腾讯2014研发笔试涉及到了0-1背包问题,由此展开了背包问题的学习。 腾讯试题:“背包题目”的基本描述是:有一个背包,能盛放的物品总重量为S,设有N件物品,其重量分别为w1,w2,…,wn,希看从N件物品中选择若干物品,所选 物品的重量之和恰能放进该背包,即所选物品的重量之和即是S。递回和非递回解法都能求得“背包题目”的一组解,试写出“背包题目”的非递回解法。 以下内容转自http://zh.wikipedia.org/zh/%E8%83%8C%E5%8C%85%E9%97%AE%E9%A2%98 背包问题 (Knapsack problem)是一种 组合优化 的 NP完全 问题。问题可以描述为:给定一组物品,每种物品都有自己的重量和价格,在限定的总重量内,我们如何选择,才能使得物品的总价格最高。问题的名称来源于如何选择最合适的物品放置于给定背包中。 相似问题经常出现在商业、 组合数学 , 计算复杂性理论 、 密码学 和 应用数学 等领域中。 也可以将背包问题描述为 决定性问题 ,即在总重量不超过 W 的前提下,总价值是否能达到 V ? 0-1背包问题,以下内容转自http://blog.csdn.net/fg2006/article/details/6766384 动态规划的基本思想: 将一个问题分解为子问题递归求解,且将中间结果保存以避免重复计算。通常用来求最优解

算法学习之贪心法(背包问题)

China☆狼群 提交于 2019-12-22 04:09:31
贪心法介绍: 一个贪心算法总是做出当前最好的选择,也就是说,它期望通过局部最优选择从而得到全局最优的解决方案。 大体步骤: 贪心策略:制定贪心策略,并选择最佳的策略实施 局部最优解:通过策略,一步一步得到局部最优解。 全局最优解:把所有的局部最优解整合到一起,还原出原来问题的最优解。 示例如下 问题描述 假设山洞中有n种宝物,每种宝物有一定重量w和相应的价值v,毛驴运载能力有限,只能运走m重量的宝物,一种宝物只能拿一样,宝物可以分割。那么怎么才能让背包装走宝物的价值最大呢? 贪心策略 每次挑选价值最大的宝物装入背包,得到的结果是否为最优? 每次挑选重量最小的宝物装入背包,得到的结果是否为最优? 每次挑选价值单位重量价值最大的宝物装入背包,得到的结果是否为最优? 分析各策略后,我们挑选第三种策略:每次挑选价值单位重量价值最大的宝物装入背包。 思路 计算每件宝物的性价比 将宝物按性价比排序 按贪心策略依次将性价比最高的宝物放入背包 若是下一性价比最高宝物重量超过剩余背包容量,将宝物拆分后再放入背包 完整代码 #include<iostream> #include<algorithm> using namespace std; const int M = 10005; struct three { double w; // 宝物重量 double v; // 宝物价值 double p;

背包问题详解

前提是你 提交于 2019-12-19 18:45:33
Nyoj289 苹果(01背包) 时间限制:3000 ms | 内存限制:65535 KB 难度:3 描述 ctest有n个苹果,要将它放入容量为v的背包。给出第i个苹果的大小和价钱,求出能放入背包的苹果的总价钱最大值。 输入 有多组测试数据,每组测试数据第一行为2个正整数,分别代表苹果的个数n和背包的容量v,n、v同时为0时结束测试,此时不输出。接下来的n行,每行2个正整数,用空格隔开,分别代表苹果的大小c和价钱w。所有输入数字的范围大于等于0,小于等于1000。 输出 对每组测试数据输出一个整数,代表能放入背包的苹果的总价值。 样例输入 3 3 1 1 2 1 3 1 0 0 样例输出 2 #include<stdio.h> #include<string.h> #define N 1001 int dp[N]; int max(int a,int b) { if(a>b) return a; else return b; } int main() { int n,v,i,j,c,w; while(scanf("%d %d",&n,&v)) { if(n==0&&v==0) break; memset(dp,0,sizeof(dp)); for(i=1;i<=n;i++) { scanf("%d %d",&c,&w); for(j=v;j>=c;j--) dp[j]=max

经典动态规划——背包问题系列一

谁说胖子不能爱 提交于 2019-12-19 15:36:07
经典动态规划——背包问题系列一 复赛前发一波博客,虽然意义不是很大了…… 本篇讲的是背包问题基础 01背包问题 简述 有N件物品和一个容量为V的背包。第i件物品的体积是c[i],价值是w[i]。求解将哪些物品装入背包可使这些物品的费用总和不超过背包容量,且价值总和最大。 思路 动态规划的基本题,背包问题之母。 对动态规划有一定了解的人应该都应理解它的原理和方程。 所谓动态规划,就是把问题分成互相联系的多个阶段决策,每一步决策都能影响答案。当然,各个阶段决策的选取不是任意确定的,它依赖于当前面临的状态,又影响以后的发展。那么我们需要确定,各阶段之间的关系是什么以及各状态如何决策才能使答案最优。 在背包问题中,我们通常把背包容量设为状态。那么我们需要决策,到底如何放置物品,才能使各阶段背包在有限容量内装价值最多的物品? 首先我们需要知道:背包容量大的状态一定由容量小的状态转移过来,因为我们要不断选物品,这样是总重量越来越大。现在我们用f[i][j]示前i件物品恰放入一个容量为v的背包可以获得的最大价值。 我们只要枚举物品,在有限的空间里取物品,并一直取max,就能在规定背包空间内跑完。 \[ dp[i][v] = max(dp[i-1][v],dp[i-1][v-c[i]]+w[i]) \] 为什么要逆着枚举?因为容量大的状态要从容量小的状态转移过来,而我们要固定每个容量去装物品

01背包 完全背包混讲(未写完)

蹲街弑〆低调 提交于 2019-12-19 15:34:59
---emmm想写几篇关于背包的,先说一下自己对01背包和完全背包的理解,望大佬指教。 //emm这是重写的,原稿由于电脑死机,一节课写的东西都没有了... 先介绍一下我同位wst..我以后博客中应该都会拿他举栗子..已得到本人允许 写这篇博客前扯点废话(违心的夸一下wst)... 设 wst是一个 冰肌玉骨 冰姿玉骨 冰肌雪肤 才貌双全 才貌兼全 才貌两全 才貌双绝 沉鱼落雁 齿白唇红 齿如含贝 齿如齐贝 齿若编贝 出水芙蓉 初发芙蓉 唇红齿白 豆蔻年华 蛾眉皓齿 耳顺之年 二八佳人 二八美人 粉白黛黑 粉白黛绿 粉白墨墨 芙蓉出水 国色天香 国色天姿 鹤发童颜 花容月貌 花容玉貌 花颜月貌 炯炯有神 绝代佳人 绝世佳人 络腮胡子 落雁沉鱼的学霸 擅长 唱 跳 打篮球..(本人自己说的) 其实wst还有一个职业(情节需要) 他是一个神偷 他有几个神奇的背包 接下来我要介绍他第一个背包 01背包 有一个黑心商店 他的商品如下 编号 重(W) 价(v) 0 2 3 1 3 4 2 4 5 3 5 8 4 9 10 wst是一个数学天才,他喜欢做事情做到最好 而且喜欢列式子 现在他的01背包w(容量)=20 他设了 一个B,B表示总价值,设了两个参数k,w B(K,W) k表示前k个物品,w表示剩下的容量 什么意思呢 ~~举个例子B(2,20)当他物品剩余量为20时, 他可以选择编号0

背包九讲(2)

感情迁移 提交于 2019-12-19 15:32:22
P02: 完全背包问题 题目 有N种物品和一个容量为V的背包,每种物品都有无限件可用。第i种物品的费用是c[i],价值是w[i]。求解将哪些物品装入背包可使这些物品的费用总和不超过背包容量,且价值总和最大。 基本思路 这个问题非常类似于 01背包问题 ,所不同的是每种物品有无限件。也就是从每种物品的角度考虑,与它相关的策略已并非取或不取两种,而是有取0件、取1件、取2件……等很多种。如果仍然按照解01背包时的思路,令f[i][v]表示前i种物品恰放入一个容量为v的背包的最大权值。仍然可以按照每种物品不同的策略写出状态转移方程,像这样: f[i][v]=max{f[i-1][v-k*c[i]]+k*w[i]|0<=k*c[i]<=v} 这跟01背包问题一样有O(N*V)个状态需要求解,但求解每个状态的时间已经不是常数了,求解状态f[i][v]的时间是O(v/c[i]),总的复杂度是超过O(VN)的。 将01背包问题的基本思路加以改进,得到了这样一个清晰的方法。这说明01背包问题的方程的确是很重要,可以推及其它类型的背包问题。但我们还是试图改进这个复杂度。 一个简单有效的优化 完全背包问题有一个很简单有效的优化,是这样的:若两件物品i、j满足c[i]<=c[j]且w[i]>=w[j],则将物品j去掉,不用考虑。这个优化的正确性显然:任何情况下都可将价值小费用高得j换成物美价廉的i

背包问题(贪心算法)

蓝咒 提交于 2019-12-19 12:39:12
  贪心算法(又称贪婪算法)是指,在对问题求解时,总是做出在当前看来是最好的选择。也就是说,不从整体最优上加以考虑,他所做出的是在某种意义上的局部最优解。   贪心算法还是比较好理解的一个算法,以前我也是这样认为的,感觉贪心就是每一步都做到最优解就可以了,但是后来结合问题发现自己的理解存在着一些问题。贪心算法比较经典的题目之一就是单源最短路径问题,这个问题在一些步骤上面我想了很久,有些细节想不通。这个问题以后有机会再讲。本次讲一讲背包问题。   背包问题就是有若干物品,每个物品有自己的价值和重量。背包有总重量。问题就是怎样将背包装的最大价值。背包问题也分很多种,贪心算法解决的是物品可以拆分的背包问题(就是物品可以分成几份装入)。这个问题用贪心还是比较好解决的。贪心选择是指所求问题的整体最优解可以通过一系列局部最优的选择,即贪心选择来达到。这是贪心算法可行的第一个基本要素,也是贪心算法与动态规划算法的主要区别。此问题就是将每次的放入看成每一步,要想解决问题,就是将每一步都放入最优解。也就是说,每一次的放入都要放入最佳的选择。讲到这里,就要说一说最佳的选择,每一次的放入的最佳的选择就是每次放入的物品都是剩余的物品中价值最大且质量最小的,这里就要引入一个物品的属性,物品的权重值。物品的权重值就是指物品的价值除以物品的质量。所以,本问题的每一次的最佳选择就是每次都选出权重值最大的物品。