背包问题动态规划

c++背包九讲之二维费用背包问题

雨燕双飞 提交于 2019-11-30 03:17:19
一、背包九讲总述 关于动态规划问题,最典型的就是背包九讲,先理解背包九讲后再总结关于动态规划的问题 1、01背包问题 2、完全背包问题 3、多重背包问题 4、混合背包问题 5、二维费用的背包问题 6、分组背包问题 7、背包问题求方案数 8、求背包问题的方案 9、有依赖的背包问题 往前四篇博文已经介绍了前四个问题,有需要的同学可以看一下!! 二、二维费用背包问题 二维费用的背包问题是指:对于每件物品,具有两种不同的费用,选择这件物品必 须同时付出这两种费用。对于每种费用都有一个可付出的最大值(背包容量)。问怎样 选择物品可以得到最大的价值。 故:对于01背包问题、完全背包问题和多重背包问题的方法都完全可以使用,只不过增加一个代价 接下来,01背包问题为例进行解答: 题目描述: 有 N 件物品和一个容量是 V 的背包,背包能承受的最大重量是 M。每件物品 只能用一次 。体积是 v[i],重量是 w[i],价值是 money[i]。 求解将哪些物品装入背包,可使物品总体积不超过背包容量,总重量不超过背包可承受的最大重量,且价值总和最大。输出最大价值。 输入格式 : 第一行3个整数,n,C, W,用空格隔开,分别表示物品件数、背包容积和背包可承受的最大重量。 接下来有 n 行,每行三个整数 v[i],w[i],money[i],用空格隔开,分别表示第 i 件物品的体积、重量和价值。

动态规划-背包问题

瘦欲@ 提交于 2019-11-29 19:23:04
一、题目描述 有 n 个物品和一个大小为 m 的背包. 给定数组 A 表示每个物品的大小和数组 V 表示每个物品的价值,问最多能装入背包的总价值是多大? 样例 样例 1: 输入: m = 10, A = [2, 3, 5, 7], V = [1, 5, 2, 4] 输出: 9 解释: 装入 A[1] 和 A[3] 可以得到最大价值, V[1] + V[3] = 9 样例 2: 输入: m = 10, A = [2, 3, 8], V = [2, 5, 8] 输出: 10 解释: 装入 A[0] 和 A[2] 可以得到最大价值, V[0] + V[2] = 10 挑战 O(nm) 空间复杂度可以通过, 不过你可以尝试 O(m) 空间复杂度吗? 注意事项 A[i], V[i], n, m 均为整数 你不能将物品进行切分 你所挑选的要装入背包的物品的总大小不能超过 m 每个物品只能取一次 二、代码 class Solution { public: /** * @param m: An integer m denotes the size of a backpack * @param A: Given n items with size A[i] * @param V: Given n items with value V[i] * @return: The maximum value *

leetcode中完全背包问题集合

谁都会走 提交于 2019-11-29 11:18:38
这两天在刷leetcode的动态规划的题目时,发现很多动态规划的题目怎么想都很难出递推公式,而看答案往往都感觉是精巧设计的,但是遇到类似的题目又不知从何下手,看了一天的博客和其他资料,发现这种类型的题目都是一类经典问题的变种:背包问题 背包问题主要有3种基本类型:01背包,完全背包,多重背包问题。 这里列出几个写的比较好的博客:大家可先行补充下基本知识(主要是leetcode中的题目不会让人立刻联想到是背包问题,所以看基本概念的目的是深入熟悉和记住递推公式的模板,方便套用)。 背包问题九讲 动态规划解决01背包问题 本文是总结leetcode中的背包变形问题的集锦,所以会不断更新,首先来看困扰我的leetcode中的二维递推公式的都长什么样: for (int i = 1; i <= m; i++) { for (int j = 0; j < n; j++) { dp[i] = min(dp[i], dp[i - coins[j]] + 1); } } 注意看红字所示,递推公式中会减去外层循环中的某个值,而不是我们常见的如下模板: for (int i = 1; i <= m; i++) { for (int j = 0; j < n; j++) { dp[i] = min( dp[i-1]+A[i] , dp[i]); } } 这种反减的模板套路就和背包问题很像

第九讲 背包问题问法的变化

若如初见. 提交于 2019-11-29 09:37:26
以上涉及的各种背包问题都是要求在背包容量(费用)的限制下求可以取到的最大价值,但背包问题还有很多种灵活的问法,在这里值得提一下。但是我认为,只要深入理解了求背包问题最大价值的方法,即使问法变化了,也是不难想出算法的。 例如,求解最多可以放多少件物品或者最多可以装满多少背包的空间。这都可以根据具体问题利用前面的方程求出所有状态的值(f数组)之后得到。 还有,如果要求的是“总价值最小”“总件数最小”,只需简单的将上面的状态转移方程中的max改成min即可。 下面说一些变化更大的问法。 输出方案 一般而言,背包问题是要求一个最优值,如果要求输出这个最优值的方案,可以参照一般动态规划问题输出方案的方法:记录下每个状态的最优值是由状态转移方程的哪一项推出来的,换句话说,记录下它是由哪一个策略推出来的。便可根据这条策略找到上一个状态,从上一个状态接着向前推即可。 还是以01背包为例,方程为 f[i][v]=max{f[i-1][v],f[i-1][v-c[i]]+w[i]} 。再用一个数组g[i][v],设g[i][v]=0表示推出f[i][v]的值时是采用了方程的前一项(也即f[i][v]=f[i-1][v]),g[i][v]表示采用了方程的后一项。注意这两项分别表示了两种策略:未选第i个物品及选了第i个物品。那么输出方案的伪代码可以这样写(设最终状态为f[N][V]): 另外

算法3:背包问题

邮差的信 提交于 2019-11-28 17:58:37
背包问题和01背包问题是很经典的关于动态规划和贪心算法的题目。 这两个问题很相似,01背包是有一个容量为c的背包,装入一些质量为w[ ]的且价值为v[ ]的物品,每次只能选择放入或者不放,不能只放一部分某个物品。求出可以让背包装最大价值的一个x[ ],其中的每一项表示第 i 个物品是否要装入。 背包问题跟01背包相似,但是可以装入部分商品。 背包问题可以用贪心算法求解,01背包则要用动态规划。 先来说01背包 举个例子: c=5,即背包的容量是5.放入以下质量和价值的物品 编号 质量w 价值v 0 1 6 1 3 12 2 2 10 根据前面的动态规划的解法,动态规划一般需要一个二维的数组存放每一步计算得到的动态结果,本例用矩阵 m 表示,行标表示商品编号 用 i 表示,列标表示变化的 j ,即容量 0 1 2 3 4 5 0 0 6 10 16 18 22 1 0 0 10 12 12 22 2 0 0 10 10 10 10 本例的最佳装法解x应该是x={0,1,1},也就是装入第二个和第三个,总最大价值为12+10=22 我写了一个简单的代码 1 #include<iostream> 2 using namespace std; 3 int m[3][6];//动态规划中的矩阵 4 int v[3]={12,10,6};//价值 5 int w[3]={3,2,1};//质量

背包问题

让人想犯罪 __ 提交于 2019-11-28 07:21:34
简介 背包问题是一类动态规划问题的统称,分有多种子类型。 01背包 给定 \(n\) 个物品,每个物品都有自己的价值 \(v_i\) 和重量 \(w_i\) 。现有一个容量为 \(W\) 的背包,求最大价值。 很容易想到每种物品只有选或者不选,那么依次枚举即可。 考虑到还需要判断能否装下这些物品,所以还需要在转移的时候维护剩余容量。 因此设子状态 \(f[i][j]\) 为当前在第 \(i\) 个物品处,包括 \(i\) 在内已经选了重量为 \(j\) 的物品的最大价值。 状态转移方程为 \(f[i][j]=max(f[i-1][j-v_i]+w[i],f[i-1][j])\) 此时的空间复杂度为 \(O(NM)\) ,可以通过滚动数组优化到 \(O(M)\) 。 事实上,还可以进行进一步优化: 由于每一层 \(i\) 之间是互相独立的(也就是说 \(f[i][j]\) 不会被 \(f[i][k]\) 更新),所以我们可以优化掉第一维,但是此时需要修改第二维的枚举顺序。 根据状态转移方程可知,第二维大的状态是由第二维小的状态转移来的,由于我们优化掉了第一维,所以必须先遍历第二维大的状态,否则将会出现覆盖的情况。 所以第一维遍历仍然顺序,第二维遍历须改为逆序。 来源: https://www.cnblogs.com/ilverene/p/11398617.html

背包型动态规划

岁酱吖の 提交于 2019-11-27 16:30:00
背包问题也是动态规划中一个很经典的问题 其问题主要框架为:有一个体积为V的背包(花费上限),有n件物品,第i件物品的体积为v[i],价值为w[i],问怎么放的最大价值。 当然,不同的题会对物品有不一样的限制,比如对物品数量的限制,对物品关系的限制,因此就有了不同种类的背包问题。 一,01背包 问题:有一个体积为V的背包,有n件物品,第i件物品的体积为v[i],价值为w[i],每件物品至多选择一次,问在不超过背包体积的前提下能获得的最大价值。 这是背包型动态规划的基础,有些背包型动态规划可以转化为01背包,从而起到优化的效果。 特点是对于第i件物品,我们只有两种选择,第一种,将这件物品放入背包,第二种,不放这种物品,显然,我们想要在当前体积限制下获得最大的价值,如果放入这件物品 会使总的价值增大,我们就放入这件物品,否则不放。 状态转移方程 dp[i][v]=max(dp[i-1][v],dp[i-1][v-w[i]+c[i]]); 1 for(int i=1;i<=n;i++) 2 for(int v=1;v<=vmax,v++) 3 { 4 if(w[i]>v) dp[i][v]=dp[i-1][v]; 5 else dp[i][v]=max(dp[i-1][v],dp[i-1][v-w[i]]+c[i]); 6 } 我们可以通过数组的重复利用优化掉一维

浅析动态规划:二、背包问题

余生长醉 提交于 2019-11-27 13:41:18
文章目录 一、01背包 二、完全背包 三、多重背包 四、混合背包 五、二维背包 六、分组背包 七、背包方案 一、01背包 有 n 件物品和一个容量为 v 的背包。第 i 件物品的费用为 w[i],价值是 c[i],在不超过背包最大容量的情况下是总价值最大。 【分析】 考虑到每种物品只有一件,所以这是一个 01背包问题,何为 01,就是对于一件物品,只有取1件或者取0件的选择。 用 f[i][j] 表示前 i 件物品消耗 j 体积获得的最大价值,显然,状态转移方程: f[i][j]=max{f[i-1][j],f[i-1][j-w[i]]+c[i]} 。 【代码段】 for ( int i = 1 ; i <= n ; i ++ ) for ( int j = m ; j >= 1 ; j -- ) { if ( j >= w [ i ] ) //如果剩余空间还能放第 i 件物品,再放和不放之间取舍 f [ i ] [ j ] = max ( f [ i - 1 ] [ j ] , f [ i - 1 ] [ j - w [ i ] ] + c [ i ] ) ; else //否则只能不放 f [ i ] [ j ] = f [ i - 1 ] [ j ] ; } 如果只用一维数组 f[i] 能不能达到一样的效果呢?把二维变成一维,用一个状态代表两个状态。 注意到上面的代码中

算法图解读书笔记 第9章 动态规划

自古美人都是妖i 提交于 2019-11-27 07:16:00
动态规划 将大问题分解成小问题,并先着手解决这些小问题。 9.1 背包问题 9.1.1 简单算法 尝试各种可能的组合,并找出价格最高的组合。 9.1.2 动态规划 先解决小背包的问题,再逐步解决原来的问题。 9.2 背包问题 先解决小问题,在逐步解决大问题 9.3 最长公共子串 9.3.1 绘制网络 9.3.2 填充网络 9.3.3 揭晓答案 9.3.4 最长公共子序列 9.3.5 最长公共自子序列解决方法 9.4 小结 来源: https://blog.csdn.net/weixin_41217899/article/details/99540986

算法设计

不羁的心 提交于 2019-11-27 03:55:47
一、分治法 递归,找最大值最小值,整数相乘,归并排序,快速排序,线性时间选择,最近点对问题 二、动态规划   0-1背包问题 ,矩阵相乘问题,装配线调度问题,最长公共子序列,最优二分检索树,凸多边形最优三角剖分 三、贪心法   背包问题,活动选择问题,哈夫曼编码,最小生成树算法(Kruskal 和 Prim) 四、回溯法   n皇后问题,子集和数问题,0-1背包问题,旅行商问题,着色问题 五、图算法   图的表示,广度优先搜索,Dijkstra算法 来源: https://www.cnblogs.com/eaglezb/p/11343106.html