背包问题动态规划

完全背包

淺唱寂寞╮ 提交于 2020-01-13 18:52:09
什么是完全背包 完全背包,就是在背包容量有限的情况下,每件物品可以选无数多件。 如何求解完全背包 完全背包和01背包一样,拥有最优子结构。所以也可以用动态规划来解。 还是先确定动态转移方程,把01背包的转移方程进行发展,可以得到 f(n,m)=max{f(n-1,m-k×w[n] )+k×v[n] │ 0≤k×w[n]≤M} K表示选k件n类物品。其实01背包也可以用这个递推式来解的,只是k非0即1。 优化动态转移矩阵 如何优化这个转移矩阵呢?我们先回顾一下01背包是怎么优化的?我们把二维矩阵优化成一维数组,但是在计算时m要逆序。为怎么呢?因为第n件物品是不能复选的。 那我们在来看看如果m不逆序会发生什么? 我先们来看看“上次计算的结果”是什么呢?“上次计算的结果”无非是两种情况 f[n-2][m] 或者是 f[n-2][m-w[n-1] ]+v[n-1] 先考虑 第二种情况叠加 的情况,就会发现。。。我们根本没法叠加。但是如果我们把转移式改成 f[n][m]=max{f[n-1][m],f[n][m-w[n]]+v[n]} 就可以叠加了(就是后面那个n不减了)。结果发现这和 f(n,m)=max⁡{f(n-1,m-2×w[n] )+2×v[n]} 是等价的。那不就正好达到了取2件i物品的目的吗。在这样叠加上去,就和取k件i物品就等价了。这时候你可能会产生这样一个问题

c++ 动态规划-01背包

∥☆過路亽.° 提交于 2020-01-10 03:28:57
动态规划 - 01背包问题 1.使用递归遍历(穷举)求解: 01背包问题:给定 n 种物品和一个重量(容量)(限定条件)为 w 的 背包 ,物品 i 的重量是 wi,其价值为 vi。(每种物品只有一个)问:如何选择装入 背包 的物品,使得装入 背包 中的物品的价值最大。 //VC6.0-------------------------- #include"stdafx.h" #include <cmath> #include <iostream> using namespace std; //----------全局变量------------ #define n 4 //number //物品数量 #define max_w 9 //weight //可承受重量(最大重量) int value[n]={2,3,4,5}; //物品价值 int weight[n]={3,4,5,6}; //物品重量 //最大价值 以及解向量 int max_v=0; int x[n]={0}; int nx[n]={0}; //当前解的情况 //-----------------------递归----------------------- void beibao01(int i,int v,int w) //第i个物品 总价值 总重量 { //物品已遍历完毕 if(i>n-1) return;

动态规划3-贪心算法-0-1背包

拈花ヽ惹草 提交于 2020-01-07 21:28:29
参考 https://zh.wikipedia.org/wiki/%E8%B4%AA%E5%BF%83%E7%AE%97%E6%B3%95 贪心算法 (英语: greedy algorithm),又称 贪婪算法 ,是一种在每一步选择中都采取在当前状态下最好或最优(即最有利)的选择,从而希望导致结果是最好或最优的 算法 。 [1] 比如在 旅行推销员问题 中,如果旅行员每次都选择最近的城市,那这就是一种贪心算法。 贪心算法在有最优子结构的问题中尤为有效。最优子结构的意思是局部最优解能决定全局最优解。简单地说,问题能够分解成子问题来解决,子问题的最优解能递推到最终问题的最优解。 贪心算法与 动态规划 的不同在于它对每个子问题的解决方案都做出选择,不能回退。动态规划则会保存以前的运算结果,并根据以前的结果对当前进行选择,有回退功能。 贪心法可以解决一些 最优化 问题,如:求 图 中的 最小生成树 、求 哈夫曼编码 ……对于其他问题,贪心法一般不能得到我们所要求的答案。一旦一个问题可以通过贪心法来解决,那么贪心法一般是解决这个问题的最好办法。由于贪心法的高效性以及其所求得的答案比较接近最优结果,贪心法也可以用作辅助算法或者直接解决一些要求结果不特别精确的问题。 贪心算法,可以针对一些不是特别复杂的问题,也就是不需要推导重来,确定子结构最优解,这个最优解就是最终解的一部分,不会像动态规划中

动态规划 ——0-1背包问题(1)

回眸只為那壹抹淺笑 提交于 2019-12-31 21:42:55
0-1背包问题 本文内容来来源于《计算机算法设计与分析》(王晓东著),是笔者的学习笔记,内容不当处,欢迎留言探讨 问题描述:给定n中物品和一背包,物品i的重量是 w i w_i w i ​ ,价值为 v i v_i v i ​ ,背包容量为c。应如何选择装入背包中的物品,使得装入背包中物品的总价值最大。 目标函数: m a x ∑ i = 1 n v i x i max\sum_{i=1}^{n}v_ix_i m a x i = 1 ∑ n ​ v i ​ x i ​ 即装入背包中的物品价值达到最大。 约束条件: ∑ i = 1 n v i x i < c \sum_{i=1}^{n}v_ix_i<c ∑ i = 1 n ​ v i ​ x i ​ < c ,即装入背包中的物品总重量小于背包的容量。 好吧,其实我看到这里已经要睡着了,脑子里想到的画面是装到背包里的东西,和重量有个线球关系,你该考虑的不该是体积么,反正我装背包,从来不担心重量。不过不要紧,清醒一下,洗把脸,心里默念,去~~~的 1、最优子结构 动态规划的本质是对问题进行分解,对每个子问题求解,从而得到原问题的解,当然,其灵魂是建立一个表格,或者什么都行,存储一部分子问题的解,避免进行重复计算。 设 ( y 1 , y 2 . . . y n ) (y_1,y_2...y_n) ( y 1 ​ , y 2 ​ . .

动态规划算法------背包问题

末鹿安然 提交于 2019-12-27 02:26:04
1、动态规划与分治法的相似点:都是将待求问题分解成若干个子问题,先求解出这些子问题,然后从子问题的解得到原问题的解 不同点:适合用动态规划求解的问题,经分解得到的子问题一般不是互相独立的。 2、动态规划算法通常用于求解具有某种最优性质的问题。在这类问题中可能有许多可行解,每一个解都对应一个值,希望找到具有最优值的解。 3、动态规划算法的有效性依赖于最优子结构 和 子问题重叠 最优子结构 指的是问题的最优解 包含了 其子问题的最优解,使得程序能以自底向上的方式递推地从子问题的最优解逐步 构造出 整个问题的最优解 子问题重叠 指的是对某些子问题重复求解多次,动态规划能存储这些解。 4、解决动态规划的问题的手段: 第一:递归:先自上到底 再 自底到上 优势:正着由大规模问题推向小规模问题,容易想 劣势:但是效率低。 第二:迭代递推: 直接自底向上 优势 效率高 劣势:不好想 5、写动态规划算法,最重要的是要找到动态规划递推式 0-1背包问题,如果有n个物品,它们的重量分别为w1,w2......wn,价值分别为v1,v2....vn,现有一个负重为k的背包,要求选择物品装入背包, 使背包中物体总价值最大。 1、背包的状态转换方程 f[i,j] = Max{ f[i-1,j-Wi]+Pi( j >= Wi ), f[i-1,j] }//前者表示放入第i件物品(如果超出重量价值为0)

动态规划--背包

懵懂的女人 提交于 2019-12-26 22:35:34
1. 01背包: 有 N 件物品和一个容量为 V 的背包。第 i 件物品的费用是 c[i],价值是 w[i]。求解将哪些物品装入背包可使价值总和最大。    对于这类问题我们我们定义f[i][j]表示在前i个物品中选总容量为j所能得到的最大价值为多少于是我们状态转移便是这样 f[i][j]=max(f[i][j],f[i-1][j-w[i]]+v[i]); int f[N][M]; void work() { memset(f,0,sizeof(f)); for(int i=1;i<=n;i++) for(int j=w[i];j<=m;j++) f[i][j]=max(f[i][j],f[i-1][j-w[i]]+v[i]); for(int i=1;i<=m;i++) ans=max(f[n][i],ans); printf("%d\n",ans); }   这样一来,我们的时间复杂度就是O(nm),空间复杂度为O(nm),但我们发现f[i]的值只与f[i-1]有关,此时我们可以用滚动数组来优化空间到O(m),为f[j]=max(f[j],[j-w[i]]+v[i]);此时我们的j就要倒序枚举,因为j只会从比它小的j那转移。 int f[M]; void work() { memset(f,0,sizeof(f)); for(int i=1;i<=n;i++) for(int

动态规划0—1背包问题

百般思念 提交于 2019-12-26 12:10:41
动态规划0-1背包问题 Ø 问题描写叙述: 给定n种物品和一背包。物品i的重量是wi,其价值为vi,背包的容量为C。问应怎样选择装入背包的物品,使得装 入背包中物品的总价值最大? Ø 对于一种物品,要么装入背包,要么不装。所以对于一种物品的装入状态能够取0和1.我们设物品i的装入状态为xi,xi∈ (0,1),此问题称为0-11背包问题。 过程分析 数据:物品个数n=5,物品重量w[n]={0,2,2,6,5,4},物品价值V[n]={0,6,3,5,4,6}, (第0位,置为0,不參与计算,仅仅是便于与后面的下标进行统一,无特别用处,也可不这么处理。)总重量c=10. Ø背包的最大容量为10,那么在设置数组m大小时,能够设行列值为6和11,那么,对于m(i,j)就表示可选物品为i…n背包容量为j(总重量)时背包中所放物品的最大价值。 以下是自己写的源代码: #include<stdio.h> #include<stdlib.h> #include<iostream> #include<queue> #include<climits> #include<cstring> using namespace std; const int c = 10; //背包的容量 const int w[] = {0,2,2,6,5,4};//物品的重量,当中0号位置不使用 。 const int

动态规划之0-1背包问题

时光总嘲笑我的痴心妄想 提交于 2019-12-25 07:30:40
给定n个物品和一个背包,物品i的重量是wi,其价值是vi,背包的容量为w,及最大载重量不超过W,在限定的总重量W内,我们如何选择物品,才能使物品的总价值最大。 具体问题: 有编号分别为a,b,c,d,e的五件物品,它们的重量分别是2,2,6,5,4,它们的价值分别是6,3,5,4,6,现在给你个承重为10的背包,如何让背包里装入的物品具有最大的价值总和? m(i,j)表示当前背包的容量为j,可选择的物品范围为i,i+1,i+2....n。所以背包问题的递推式如下 m(i,j)={max{ m(i+1,j) ,m(i+1,j-w[i])+v[i]}(wi<=j), m(i+1,j)(wi>j)};( 但看公式还是比较抽象的 ) 下面具体的分析 现在我们才去的分析方法是从左往右,从下往上。 首先动态规划过程的表如下 这张表是从下往上从左往右的分析 当i=5时表示当前只有e一个物体,j从1到10慢慢增加表示背包容量在不断的增大,当j<=3的时候,背包的当前容量是小于e的,所以此时不能将物品加入到背包当中。当j>=4的时候恰好只有一个e所以背包最大为6。 当i=1,j=8的时候m[2][8]=9(不加上a),当加上a之后之后m[i+1][j-w[i]]+v[i]=m[2][6]+v[1]= 9+6=15.根据前面的公式m[i][j]=m[1][8]=15/其他的分析也是一样的

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-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 动态规划的基本思想: 将一个问题分解为子问题递归求解,且将中间结果保存以避免重复计算。通常用来求最优解