#动态规划 0-1背包问题思路概述

01背包问题是动态规划中的经典问题。

本篇文章主题:分析与优化最基本的01背包问题,对此类问题解题有一个基本的解题模板。

问题概述:

有一个背包,他的容量为C(Capacity)。现在有n种不同的物品编号分别为0、1....n-1。其中每一件物品的重量为w(i),价值为v(i)。问可以向这个背包中放入哪些物品,使得在不超过背包容量的基础上,背包内物品价值最大。

思路:

1.暴力法。

每一件物品都可以放进背包,也可以不放进背包。找出所有可能组合一共2^n种组合

时间复杂度:O((2^n)*n)

2.动态规划法。

我们首先使用递归函数自上而下进行思考。

明确两点:

第一、递归函数的定义

第二、数据结构

函数定义:

F(n,C)递归函数定义:将n个物品放入容量为C的背包,使得价值最大。

这里要注意一下,第二个参数一定是剩余容量。我们通过使用剩余容量来控制价值。

F(i,c) = F(i-1,c)

       = v(i) + F(i-1 , c-w(i))

状态转移方程:

F(i,c) = max( F(i-1 , c) , v(i) + F(i-1 , c-w(i) ) )

即,当前价值的最大值为,不放入第i个物品(对应剩余容量为c)和放入第i个物品(对应剩余容量为C-w(i))两种情况的最大值。

数据结构:

借某盗版视频中的一个例子:

我们这里选择一个二维数组,来迭代记录处理的结果。

这个二维数组dp[n][C] 其中n为物品数量,C为最大容量。

储存的值dp[i][j]含义为:考虑放入0~i 这些物品, 背包容量为j

我们考虑放入第一个物品。

由于第一个物品,编号为0,重量为1,价值为2。

对于容量为0的背包,放不下该物品,所以该背包价值为0.

其余容量1~5,均可放下该物品。所以只考虑物品0,不同背包大小对应的最大可能价值如图。

第一行处理为初始化,从第二行开始进行迭代。

第二行开始,就需要单独处理。

考虑dp[1][0],背包容量为0,理所应当为0

考虑dp[1][1],此处我们依旧无法放入物品1,所以我们使用上一层的结果,即0~0物品在容量为1背包情况的最大价值。

考虑dp[1][2],此处我们终于可以放下物品1了,所以我们考虑如果要放下物品1,剩余背包最大的可能价值,即dp[0][0]

我们对比上一层的情况,以及掏空背包放入物品2的情况。发现最大值为后者,所以dp[1][2]为10

同上,我们掏出可以放下物品1的空间,考虑此时最大价值,即dp[0][1]。对比他和上一层dp[0][3]的大小,发现前者大。

故此时dp[1][3]为dp[0][1]+v[1] = 16.

以此类推,我们每次清空对应物品大小的背包,然后放入对应物品,对比不放入物品的上一行。求出最大值

依次填入dp[][]得出最终的二维数组。

代码如下

class Knapasack01{
    public :
        int knapsack01(int[] w,int[] v,int C){
//w为0-~n-1物品对应价值
//v为0~n-1物品对应重量。
//C为背包容量

            int n = w.length();
            if(n == 0)
                return 0;
   //动态规划记忆数组。
            int[][] dp = new int[n][C];
//初始化第一行。
            for(int j=0 ; i<= C ; j++)
                dp[0][j] = (j>=w[0]?v[0]:0);

            for(int i=1 ; i<n ; i++)
                for(int j=0 ; j<C ; j++){
                    dp[i][j] = dp[i-1][j];
                    if(j>=w[i])
                        memo[i][j] = (int)Math.max(dp[i][j] , v[i]+dp[i][j-w[i]]);
                }
          return dp[n-1][C];
        }
}

原文地址:https://www.cnblogs.com/rainxbow/p/9713749.html

时间: 2024-10-28 21:32:54

#动态规划 0-1背包问题思路概述的相关文章

动态规划0—1背包问题

动态规划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,不參与计算,仅

动态规划--0,1背包问题(再也不怕类似背包问题了)

这种类型问题三大要素:总重量.每件物品重量.每件物品价值,问最终能够塞进背包中的价值最大是多少?应该怎么选择物品? 当然也不一定是这些,例如上节所说的矿工挖矿:总人数.挖每座矿的人数.每座矿的金子数. 也就是说,只要出现了这三大要素,都可以视为0,1背包问题(物品不可拆分) 动态规划三要素:边界.最优子结构.状态转移方程. 我们一步步进行解析: 初始化:物品总重量:c=8,物品类别:n=['a','b','c','d'],物品重量:w=[2,4,5,3],物品价值:v=[5,4,6,2] 假设我

动态规划算法实现部分——0/1背包问题

代码: import java.util.*; import java.util.Scanner; /* *动态规划思想解决0/1背包问题 */ public class Main{ public static void main(String[] args){ Scanner in=new Scanner(System.in); System.out.println("输入背包的容量"); int bagCap=in.nextInt(); //背包的容量 System.out.pri

动态规划算法求解0,1背包问题

首先我们来看看动态规划的四个步骤: 1. 找出最优解的性质,并且刻画其结构特性: 2. 递归的定义最优解: 3. 以自底向上的方式刻画最优值: 4. 根据计算最优值时候得到的信息,构造最优解 其中改进的动态规划算法:备忘录法,是以自顶向下的方式刻画最优值,对于动态规划方法和备忘录方法,两者的使用情况如下: 一般来讲,当一个问题的所有子问题都至少要解一次时,使用动态规划算法比使用备忘录方法好.此时,动态规划算法没有任何多余的计算.同时,对于许多问题,常常可以利用其规则的表格存取方式,减少动态规划算

[转载]动态规划之0-1背包问题

作者:Hawstein出处:http://hawstein.com/posts/dp-knapsack.html 一切都要从一则故事说起. 话说有一哥们去森林里玩发现了一堆宝石,他数了数,一共有n个. 但他身上能装宝石的就只有一个背包,背包的容量为C.这哥们把n个宝石排成一排并编上号: 0,1,2,-,n-1.第i个宝石对应的体积和价值分别为V[i]和W[i] .排好后这哥们开始思考: 背包总共也就只能装下体积为C的东西,那我要装下哪些宝石才能让我获得最大的利益呢? OK,如果是你,你会怎么做?

【动态规划】简单背包问题II

问题 B: [动态规划]简单背包问题II 时间限制: 1 Sec  内存限制: 64 MB提交: 21  解决: 14[提交][状态][讨论版] 题目描述 张琪曼:“为什么背包一定要完全装满呢?尽可能多装不就行了吗?” 李旭琳:“你说得对,这和墨老师曾告诉我们的‘日中则昃,月满则亏’是一个道理.”所以,现在的问题是,她们有一个背包容量为v(正整数,0≤v≤20000),同时有n个魔法石(0≤n≤30),每个魔法石有一个体积 (正整数).要求从n个魔法石中,任取若干个装入包内,使背包的剩余空间为最

【动态规划】完全背包问题

贵有恒,何必三更起五更眠:最无益,莫过一日曝十日寒. [动态规划]完全背包问题 时间限制: 1 Sec  内存限制: 64 MB 题目描述 话说张琪曼和李旭琳又发现了一处魔法石矿(运气怎么这么好?各种嫉妒羡慕恨啊),她们有一个最多能装m公斤的背包,现在有n种魔法石,每种的重量分别是W1,W2,…,Wn,每种的价值分别为C1,C2,…,Cn.若每种魔法石的个数足够多,求她们能获得的最大总价值. 输入 第一行为两个整数,即m,n. 以后每行为两个整数,表示每块魔法石的重量和价值. 输出 获得的最大总

动态规划解决0-1背包问题

这几天算法老师布置了一个作业是关于背包问题的,在这里记录一下解决的过程: 一:背包问题的描述 有n1,n2,n3....个物品,每个物品的重量为w1,w2,w3.....,每个物品的价值为v1,v2,v3....,现在有一个承重量为C的背包,求出要怎样放物品才能使的装入背包的物品价值总和最大.由于每个物品只有一个,并且只能选择放或不放,因此用0表示物体没有放进背包中,1表示物体放进背包中 二:分析过程(以具体的例题来分析) 题目描述: 现有一个可以承重为6的背包bag,以及3个物品,它们的重量分

求解0/1背包问题

动态规划 //求解0_1背包问题 //动态规划 #include<stdio.h> #define MaxN 20 #define MaxW 100 int knap(int f[MaxN][MaxW],int w[],int v[],int W,int n){ //动态规划求数组f[][] int i,r; for(i=0;i<=n;i++) f[i][0] = 0; for(r=0;r<=W;r++) f[0][r] = 0; for(i=1;i<=n;i++){ for