精华内容
下载资源
问答
  • 背包问题动态规划

    2019-06-19 11:57:55
    背包问题 有n个物品,每件物品的重量为w,价值为v,问:当背包重量容量为W时,背包的最大价值为多少? 解决:动态规划 可通过递推的方式计算最大价值,想知道n个物品的最大价值,可如下考虑: 1、假如第n个物品的...

    背包问题

    有n个物品,每件物品的重量为w,价值为v,问:当背包重量容量为W时,背包的最大价值为多少?

    解决:动态规划

    可通过递推的方式计算最大价值,想知道n个物品的最大价值,可如下考虑:
    1、假如第n个物品的重量大于W,则背包的最大价值为前n-1个物品的最大价值;
    2、假如第n个物品的重量小于W,则背包的最大价值为(前n-1个物品的最大价值)和
    (前n个物品重量小于W-w[n]的最大价值加上第n个物品的价值)中的最大值,即为
    max(maxvalue(n-1,W),maxvalue(n-1,W-w[n])+v[n])
    由于我们知道没有物品时的价值为0,W为0时价值也为0,这样我们可得到初始条件
    然后递推即可得到n个物品的最大价值。
    代码如下:

    #include<iostream>
    using namespace std;
    int max(int a,int b)
    {
        return a>b?a:b;
    }
    int dpweight(int v[], int w[], int W)
    {
    	int value[6][1000] = { 0 };
    	//for (int i = 0; i < n; i++)
    		//value[i][0] = 0;
    	//for (int j = 0; j <= W; j++)
    	//	value[0][j] = 0;
    	for (int i = 1; i <= n; i++)
    	{
    		for (int j = 1; j < W + 1; j++)
    		{
    			if (j < w[i])//w[i]第i个东西的重量
    				value[i][j] = value[i - 1][j];
    			else
    				value[i][j] = max(value[i - 1][j], value[i - 1][j - w[i]] + v[i]);
    
    		}
    	}
    	return value[n][W];
    }
    
    int main()
    {
    	int dpweight(int v[], int w[], int W);
    	int v[] = { 0, 1, 2, 3, 4 };
    	int w[] = { 0, 1, 2, 3, 4 };
    	int W = 10;
    	cout << dpweight(v, w, W);
    
    	
    	return 0;
    }
    
    展开全文
  • 01背包问题 动态规划

    2020-04-13 09:44:23
    01背包问题 动态规划 01背包问题是一个很经典的动态规划问题了,其特点在于对于当前物品选或不选进行判断 接下来看代码: class Back { static int[] V, M; static int[][] B; public static void main(String[] ...

    01背包问题 动态规划

    01背包问题是一个很经典的动态规划问题了,其特点在于对于当前物品选或不选进行判断
    接下来看代码:

    class Back {
    	static int[] V, M;
    	static int[][] B;
    
    	public static void main(String[] args) {
    		Scanner sc = new Scanner(System.in);
    		int n = sc.nextInt();// 有多少物品
    		int m = sc.nextInt();// 背包容量是多少
    		V = new int[n + 1];// 每个物品的重量
    		M = new int[n + 1];// 每个物品的价值
    		B = new int[n + 1][m + 1];// 当装了n件商品,且剩余容量为m时的最大价值
    		for (int i = 1; i <= n; i++) {
    			V[i] = sc.nextInt();
    			M[i] = sc.nextInt();
    		}
    
    		for (int i = 1; i <= n; i++) {// 第i件物品
    			for (int j = 1; j <= m; j++) {// 当前背包容量
    				if (V[i] > j) {// 如果该物品比剩余容量大
    					B[i][j] = B[i - 1][j];// 不拿
    				} else {
    					// 判断拿还是不拿
    					int value = Math.max(B[i - 1][j - V[i]] + M[i], B[i - 1][j]);
    					B[i][j] = value;
    				}
    			}
    		}
    		System.out.println(B[n][m]);
    	}
    }
    
    
    展开全文
  • 作为动态规划(DP)中的经典问题背包问题,有以下三类子问题,分别为:0-1 背包问题、完全背包问题和多重背包问题。卜老师上课提到的主要为0-1 背包问题背包问题顾名思义,就是将一些物品放到一个背包中,背包对物体...

        作为动态规划(DP)中的经典问题背包问题,有以下三类子问题,分别为:0-1 背包问题、完全背包问题和多重背包问题。卜老师上课提到的主要为 0-1 背包问题。背包问题顾名思义,就是将一些物品放到一个背包中,背包对物体有重量限制,而我们需要的是背包中物体的总价值尽可能地多,其本质是有约束的优化问题。

        借用老师上课的图如下:

    da112a151475246a595289991077a45d.png

        转换为有约束的优化问题的数学表示如下:

    68dd8e5abc2666accfc7cd55e8399c81.png

        目标函数为每类物品价值总和,约束条件1为每类物品重量和不超过背包限重,约束条件2为每类物品的选取数量约束。不同的背包问题主要差别在于每类物品选取数量的约束,也就是  。

        显然,背包问题的本质是线性的有约束的优化问题,理论上也可以用线性规划解决,但这里只分析动态规划方法。

    01 "0-1"背包问题

        0-1背包问题中,每类物品的选取只有:选-1or 不选-0,即  ,有约束优化问题,表示为如下:

    61aa65c7d0e4d18a8fa09e3a5c343275.png

        0-1 背包问题老师上课已经讲得很多了,这里直接给出子问题和状态转移方程:

        子问题:当背包容量为 j 时,前 i 个物品所能达到的最大价值。

        状态转移方程:面对背包容量为 j ,我们需要决策是不是需要放入第 i 个物品。如果包容量 j 放不下第 i 个物品,那么很简单,前 i 个物品所能达到的最大价值就是前 i-1个物品所能达到的最大价值;如果放得下,那么需要分析放第 i 个物品与不放第 i 个物品达到包容量 j 时的价值差异。公式表示如下

    1723429285f09761f1d28173d69404b4.png

        借用卜老师课件的数据我们完善一下 OPT 表格如下:

    8a7fad3e365f03ebd0ca8b0ace71ded1.png

        最后我们得到的最优的背包价值为$15,选择的物品为 2kg/$2、1kg/$2、1kg/$1 和4kg/$10。

        复杂度分析:OPT 表格中的状态数量为 W*N,W 为背包限重,N 为物品数量,状态转移复杂度为 O(1),综合是时间复杂度为 O(W*N),空间复杂度为 O(W*N),类似背包问题都可以用一维数组更新代替二维数组(因为二维数组是从左往右从上到下按序生成状态值),所以空间复杂度可以优化到 O(W)。

    02 完全背包问题

        完全背包问题中,每类物品的选择都是不收限制的,也就是说  可以取到正无穷,因此有约束的优化问题表示如下:

    07e2a5988fa29dcac07be62e96d8252e.png

        首先我们按照常规理解来做:

        子问题:当背包容量为 j 时,前 i 个物品所能达到的最大价值。

        状态转移方程:面对背包容量为 j ,我们需要决策放入几个第 i 个物品。如果包容量j放不下第 i 个物品,那么很简单,前 i 个物品所能达到的最大价值就是前i-1个物品所能达到的最大价值,与 0-1 背包问题一致;如果放得下,那么需要分析放 0,…,K 个第 i 个物品达到包容量 j 时的价值差异。

        公式表示如下:

    ca60a0bd8392a954cf16c7e9b17db65c.png

        我们分析下这个时候的时间复杂度,OPT 表格中的状态数量仍然为 W*N,W 为背包限重,N 为物品数量,状态转移复杂度为 O(K),其中  ,时间复杂度为  ,这显然是我们不希望看到的,我们希望仍然像 0-1 背包一样,状态转移复杂度为 O(1)。

        一种方法是利用本层 OPT 状态转移数,根据子问题描述,本层的 OPT 状态转移数  已经包含了我们需要决策的第 i 个物品,决策的问题从选择几个第 i 个物品变为是否再次放入一个第 i 个物品。状态转移复杂度重新降为 O(1)。

        因此我们将状态转移方程描述为如下:

        状态转移方程:面对背包容量为 j ,我们需要决策放入是否再次放入第 i 个物品。如果包容量 j 放不下第 i 个物品,那么前 i 个物品所能达到的最大价值就是前 i-1 个物品所能达到的最大价值;如果放得下,那么需要分析再次放入一个第 i 个物品达到包容量 j 时的价值与不放第 i 个物品达到的最大价值之间的差异。至于在放这个物品前已经放了几个第 i 个物品,由于已经在  经过了决策,因此在决策  时不需要考虑之前背包里已经存在的第 i 个物品的数目。

        表达式如下:

    3c458a77de7479253f9d7ae6aac07b1c.png

        同样用例题完成 OPT 表格

    e0a671859e15d5e668dfc3ac58997881.png

        最后我们得到的最优的背包价值为$36,选择的物品为 1kg/$2 选 3 件、4kg/$10 选 3 件。

        复杂度分析:OPT 表格中的状态数量为 W*N,W 为背包限重,N 为物品数量,状态转移复杂度为 O(1),综合是时间复杂度为 O(W*N),空间复杂度为 O(W*N),同样,该背包问题都可以用一维数组更新代替二维数组,所以空间复杂度可以优化到 O(W)。

        值得注意的是:0-1 背包问题在遍历背包容量使可以正序也可以逆序,因为在生成OPT(i,j)使我们用到的只有上层状态数,而在完全背包问题下,遍历背包容量只可以正序,因为我们需要用到同层左侧的状态数,只有先生成左侧状态数,才能生成当前状态数。

    03 多重背包问题

        多重背包问题提供了每种物品的数量限制,是介于 0-1 背包问题和完全背包问题中间的问题,有约束优化问题表示如下:

    700e2c3cc6ae90ce990224dd516da667.png

        我们同样可以按照常规方法去做:

        子问题:当背包容量为 j 时,前 i 个物品所能达到的最大价值。

        状态转移方程:面对背包容量为 j ,我们需要决策放入几个第 i 个物品。如果包容量 j 放不下第 i 个物品,前 i 个物品所能达到的最大价值就是前i-1个物品所能达到的最大价值;如果放得下,那么需要分析放 0,…,  个第 i 个物品达到包容量 j 时的价值差异。

        公式表示如下:

    f715e67d863bd4447f0ce632a9870f18.png

        同样分析下时间复杂度,OPT 表格中的状态数量仍然为 W*N,W 为背包限重,N 为物品数量,状态转移复杂度为   , 时间复杂度为  

        https://www.kancloud.cn/kancloud/pack/70127  背包问题九讲中有对多重背包问题的优化,可以将时间复杂度降低至  。基本的策略是将第 i 种物品划分成若干件,划分标准在 blog 里有详细的说明。这里用 blog 中的一个例子,当    时,物品被划分为系数是 1,2,4,6 的四件物品,当你想取任意数目的  时,都可以用这四个系数组合而成。这样完成了将第 i 种物品分成了    种物品的 0-1 背包问题,复杂度从需要决策放入 0…13 件第 i 种物品变为决策是否放入第  种物品。

        同样用例题完成 OPT 表格,我们设置物品数量限制c=(3,3,2,3,2)

    fd015c7f2cd1407a2031f3a94022f15d.png

        最后我们得到的最优的背包价值为$29,选择的物品为 2kg/$2 选 2 件、1kg/$2 选 2 件、1kg/$1 选 1 件、4kg/$10 选 2 件。

    04 混合背包问题

        混合背包问题将上述三种背包问题进行混合,即有的物品只能放一件,有的可以放多件,有的可以放无穷多件。很显然背包问题涉及的子问题都是完全一致的,即 OPT(i,j)中的状态数表示的含义是完全一致的。因此只需要按类选择不同的状态转移方程就行,如下所示:

    89799fc37de5ec2d9226b0070781551e.png

    05 结语

        背包问题作为动态规划中的基础问题,延伸出了许许多多多种多样的变形。通过对背包问题这一基础问题的学习和总结,或许能帮助我们加深对动态规划的理解,也能对那些看上去比较难的算法问题提供解题思路。

    展开全文
  • 完全背包问题动态规划c++

    千次阅读 2016-02-18 11:47:01
    完全背包问题动态规划c++【脑细胞不够用了T^T
    完全背包问题
    【问题描述】
      设有n种物品,每种物品有一个重量及一个价值。但每种物品的数量是无限的,同时有一个背包,最大载重量为M,今从n种物品中选取若干件(同一种物品可以多次选),使其重量的和小于等于M,而价值的和为最大。
    【输入格式】
    第一行:两个整数,M(背包容量,M<=200)N(物品数量,N<=30)
    2..N+1行:每行二个整数Wi,Ci,表示每个物品的重量和价值。
    【输出格式】
         仅一行,一个数,表示最大总价值。
    【样例输入】knapsack.in
         10  4
         2  1
         3  3
         4  5
         7  9
    【样例输出】knapsack.out
      max=12
     
     接下来要解决的是完全背包问题,比起01背包,完全背包问题不同的是它所有背包的数量都是无限大的。所以对于物品i,我们要做的不仅仅是选择加上i或者不加上i,而变成了加上1,2,3……个i小妖精【x
    同样,用f[i][v]表示前i个物品,在总重不超过v时的最大值。我们假设一个k为i物品的数量,那么c[i]每次加上的应该是k-1时的最优解。即
    f[i][v]=max(f[i-1][v],f[i][v-w[i]]+c[i])
    需要注意的是,在完全背包中,我们是从小到大依次增加物品i的数量,那么相应的v的值也不断变大,所以v循环应从1——m(额这一点其实我也不太明白O(∩_∩)O||||哈哈~)
     
    附上程序
    <span style="font-size:24px;color:#666666;">#include<iostream>
    #include<cstdio>
    using namespace std;
    int m,n,w[31],c[31],f[31][201];
    
    int main()
    {
    	scanf("%d%d",&m,&n);
    	for(int i=1;i<=n;++i)
    	scanf("%d%d",&w[i],&c[i]);
    	for(int i=1;i<=n;++i)
    	for(int v=m;v>=0;--v)
    	{
    		if(v-w[i]>=0)
    		f[i][v]=max(f[i-1][v],f[i][v-w[i]]+c[i]);
    		else f[i][v]=f[i-1][v];
    	}
    	cout<<"max="<<f[n][m];
    	return 0;
    }</span>

    展开全文
  • 0-1背包问题动态规划详解及代码,下载使用,0-1背包问题动态规划详解及代码。
  • 01背包问题 动态规划 ** 1.动态规划 什么是动态规划动态规划就是将一个大问题不断向下拆分成小问题,直到拆分出的小问题可以求出其解,然后将小问题的解不断的向上合并,最终得到大问题的解决方案。   2.01背包...
  • 01背包问题属于经典的动态规划问题,场景描述如下:形象描述:贼,夜入豪宅,可偷之物甚多,而负重能力有限,偷哪些才更加不枉此行?进一步抽象的话,就是:给定个物品,每种物品都有自己的重量和价值,在限定的总...
  • 关于背包问题动态规划代码的理解和应用—— 首先,关于背包问题动态规划的详细讲解在https://v.youku.com/v_show/id_XMTQ3MzI0NzI2OA==.html这个视频链接有详细的介绍,在此引用某位大神制作的视频表示感谢,同时也...
  • 背包问题动态规划的经典例题,最终的目的是使用一个空间有限的背包装下的物品的价值最大,即实现背包的最大效益。根据不同的条件限制,此类问题可以分为0_1背包问题,完全背包问题,多重背包问题。 1、0_1背包 ...
  • 0-1背包问题动态规划算法题目描述: Java实现:import java.util.Scanner;public class Knapsack { public static void main(String[] args) { Scanner scan = new Scanner(System.in); // n = 4, c = 5; // w
  • 0/1 背包问题 动态规划 有为N件物品,它们的重量w分别是w1,w2,…,wn,它们的价值v分别是v1,v2,…,vn,每件物品数量有且仅有一个,现在给你个承重为M的背包,求背包里装入的物品具有的价值最大总和? 链接:...
  • public class Test7 {/*** @param args* 动态规划问题,0-1背包问题* f[i,j]表示在前 i 件物品中选择若干件放在所剩空间为 j 的背包里所能获得的最大价值* f[i,j]=max{f[i-1,j-Wi]+Pi (j>=Wi), f[i-1,j]}* 核心...
  • 国王的金矿:01背包问题 动态规划解法 题目描述 有一个国家发现了 n 座金矿,每座金矿的黄金储量不同,需要参与挖掘的工人数也不同。 参与挖矿工人的总数是 m 人。 每座金矿要么全挖, 要么不挖,不能派出一半人挖取...
  • 0_1背包问题动态规划方法求解python代码 递推公式 def Bag(n, W, V, C): C = int(C) # 容量C n = int(n) # 物品个数 w = W.split(',') w = [int(i) for i in w] # 物品重量数组 v = V.split(',') v = [int(i)...
  • 0_1_2背包问题动态规划方法求解python代码 0_1背包递推公式 0_1_2背包问题则为,可对一件物品放1个或者2个,0为不放。设计算法时比0_1背包问题多加一个限制条件 def ZeroOneTwoBag(n, W, V, C): C = int(C) # 容量...
  • 0-1背包问题 动态规划 分支限界 回溯 贪心四种方法
  • // 利用动态规划解决0-1背包问题using System;using System.Collections.Generic;using System.Linq;using System.Text;namespace Knapsack_problem// 背包问题关键在于计算不超过背包的总容量的最大价值{class ...
  • 01背包问题动态规划法求解

    千次阅读 2012-07-27 09:04:29
    01背包问题动态规划法求解   一问题描述: 有N件商品,每种商品都有各自的重量和价值,有一个背包,总容量是V。现在从这N种商品中挑选若干件放入背包中,要求每种商品最多放入一次,要使放入背包中商品总价值...
  • 01背包问题解决方法不少,动态规划是其中之一,动态规划的问题解题思路都差不多(一些浅见),基本要素是最优子结构性质,子问题重叠性质,自底向上的求解方法。只要了解了基本要素,那么这种题型也会更好理解。本题...
  • 课程的随堂作业,C语言的,用dev就能运行,萌新代码,勿喷,仅仅帮助不想写作业的朋友方便一下,反正老师也不会仔细检查的
  • 看成是两堆石头,用动态规划来求,当其中一堆重量最接近sum/2时碰撞后消耗的重量最多,剩下重量最少,即求sum/2的背包里最多能装多少重量的物品 public int lastStoneWeightII(int[] stones) { int sum = 0; int[]...
  • import numpy as np # 背包问题 # 第一阶段:递归式求解 def package(capacity, index, weightList, valueList): if capacity <= 0 or index < 0: return 0 else: if weightList[index] <= c...
  • 0-1背包问题动态规划

    2016-03-08 15:57:27
    基本的0-1背包问题。这里的物品一般指花瓶、玉器什么的,要么拿,要么不拿,只有0和1两种状态,所以也叫0-1背包。...其实,0-1背包是DP的一个经典实例,可以用动态规划求解。0-1背包问题: 有N件物品和
  • 01背包问题动态规划

    2018-09-10 21:17:33
    动态规划的精髓我还是没有领会到啊,得好好琢磨一下建表的意义,以及那些表到底里面包含些内容,怎样调取其中的内容得到自己想要的元素。 可以参考了这位博主的分析...
  • 0-1背包问题动态规划解法

    千次阅读 2012-09-29 18:33:14
     我们给出一个待测试用例的完整的0-1背包问题动态规划解法的C语言源码: #include #include void knappsack(int *w,int *v,int c,int n,int m[][10]) { int k=n-1; int t_v; for(int j=0;j;j++) {
  • 动态规划是用空间换时间的一种方法的抽象。其关键是发现子问题和记录其结果。然后利用这些结果减轻运算量。 比如01背包问题。 因为背包最大容量M未知。所以,我们的程序要从1到M一个一个的试。比如,开始任选N件...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 9,165
精华内容 3,666
关键字:

背包问题动态规划