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

  0-1背包问题是: 一个背包能承受的最大容量为max_weight,  现在有n个物品, 它们的重量分别是{w1,w2,w3,......wn}, 和价值分别是{v1,v2,......vn}, 现在要求在满足背包装载的物品不超过最大容量的前提下,保证装载的物品的价值最大?

动态规划求解过程可以这样理解:

  对于前i件物品,背包剩余容量为j时,所取得的最大价值(此时称为状态3)只依赖于两个状态。

  状态1:前i-1件物品,背包剩余容量为j。在该状态下,只要不选第i个物品,就可以转换到状态3。

  状态2:前i-1件物品,背包剩余容量为j-w[i]。在该状态下,选第i个物品,也可以转换到状态3。

  因为,这里要求最大价值,所以只要从状态1和状态2中选择最大价值较大的一个即可。

   状态转换方程:

  dp( i,j ) = Max( dp( i-1, j ), dp( i-1, j-w[i] ) + v[i] )

  dp( i,j )表示前i件物品,背包剩余容量为j时,所取得的最大价值。

  下面是java的demo代码:

private int[] v;private int[] w;private static int[][] c;private int weight;

private int[] flag = new int[5];

public Greedy(int weight, int[] v, int[] w, int maxWeight) {    this.w = w;    this.v = v;    this.weight = weight;    this.c = new int[v.length][this.weight + 1];}

public void solve() {    int len = w.length;

for (int i = 1; i < len; i++) {        for (int j = 1; j <= weight; j++) {

//第i件物品要么放,要么不放            //如果第i件物品不放的话,就相当于求前i-1件物体放入容量为j的背包获得的最大价值            //如果第i件物品放进去的话,就相当于求前i-1件物体放入容量为j-w[i]的背包获得的最大价值            if (w[i] > j) {                c[i][j] = c[i - 1][j];            } else {                // j > w[i]                if (c[i - 1][j] > c[i - 1][j - w[i]] + v[i]) {                    c[i][j] = c[i - 1][j];                } else {                    c[i][j] = c[i - 1][j - w[i]] + v[i];                }            }        }    }

//下面求解哪个物品应该放进背包    int i = v.length - 1, j = weight;    while (c[i][j] != 0) {

if (c[i - 1][j - w[i]] + v[i] == c[i][j]) {            flag[i] = 1;            j = j - w[i];            i--;        }    }

for (i = 1; i < v.length; i++) {        if (flag[i] == 1) {            System.out.print("重量" + w[i]);            System.out.println("价值为" + v[i]);        }    }}

public static void main(String[] args) {    int[] v = {0, 4, 5, 6};    int[] w = {0, 3, 4, 5};

int weight = 10;    Greedy knapsack = new Greedy(weight, v, w, weight);    knapsack.solve();}
时间: 2024-12-14 18:14:44

动态规划求解0-1背包问题的相关文章

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

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

求解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

基础算法(七)——动态规划【0/1背包问题】

首先,对于动态规划,我来做一个简短的介绍,相信各位都看得懂.动态规划(dynamic programming)是运筹学的一个分支,是求解决策过程(decision process)最优化的数学方法.先给一道最简单的例题(小学奥数水平): 这就是一个模拟的动态规划法! 好了,现在开始认识一下最简单的动态规划实例:0/1背包. [问题描述]有一位旅行者要出远门,到商店里去筹备东西.在商店里,摆放了n样物品,每种物品有各自的体积,但是每种物品只有一件.这个旅行家有一个限制装V个体积的物品的背包,但是这

hdu2602Bone Collector ——动态规划(0/1背包问题)

Problem Description Many years ago , in Teddy’s hometown there was a man who was called “Bone Collector”. This man like to collect varies of bones , such as dog’s , cow’s , also he went to the grave …The bone collector had a big bag with a volume of

《算法导论》读书笔记之第16章 0-1背包问题—动态规划求解

原文:http://www.cnblogs.com/Anker/archive/2013/05/04/3059070.html 1.前言 前段时间忙着搞毕业论文,看书效率不高,导致博客一个多月没有更新了.前段时间真是有些堕落啊,混日子的感觉,很少不爽.今天开始继续看算法导论.今天继续学习动态规划和贪心算法.首先简单的介绍一下动态规划与贪心算法的各自特点及其区别.然后针对0-1背包问题进行讨论.最后给出一个简单的测试例子,联系动态规划实现0-1背包问题. 2.动态规划与贪心算法 关于动态规划的总结

1008-----算法笔记----------0-1背包问题(动态规划求解)

1.问题描述 给定n种物品和一个背包,物品i的重量是wi,其价值为vi,背包的容量为C.问:应该如何选择装入背包的物品,使得装入背包中物品的总价值最大? 2.问题分析 上述问题可以抽象为一个整数规划问题,即求满足 (a)Σwixi ≤ C:(b)xi ∈(0,1),  1≤i≤n:条件下,∑vixi最大时的一个物品xi序列.分析问题可以发现,该问题具有最优子结构性质,那么就可以尝试用动态规划方法求解,而动态规划求解的关键就是列出问题的递归关系表达式. 设m(i,j)为背包容量为j,可选物品为i,

0/1背包问题的动态规划法求解 —— Java 实现

0/1背包问题的动态规划法求解,前人之述备矣,这里所做的工作,不过是自己根据理解实现了一遍,主要目的还是锻炼思维和编程能力,同时,也是为了增进对动态规划法机制的理解和掌握. 值得提及的一个问题是,在用 JAVA 实现时, 是按算法模型建模,还是用对象模型建模呢? 如果用算法模型,那么 背包的值.重量就直接存入二个数组里:如果用对象模型,则要对背包以及背包问题进行对象建模.思来想去,还是采用了对象模型,尽管心里感觉算法模型似乎更好一些.有时确实就是这样,对象模型虽然现在很主流,但也不是万能的,采用

动态规划算法实现部分——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

动态规划求解最长公共子序列

动态规划算法与分治法类似,其基本思想也是将待求解问题分解成若干个子问题,先求解子问题,然后从这些子问题的解得到原问题的解.与分治法不同的是,适合于用动态规划求解的问题,经分解得到的子问题往往不是互相独立的.若用分治法来解决这类问题,则分解得到的子问题数目太多,以至于最后解决原问题需要耗费指数时间.然而,不同子问题的数目常常只有多项式量级.在用分治法求解时,有些子问题被重复计算了许多次.如果我们能够保存已解决的子问题的答案,而在需要时再找出已求得的答案,这样就可以避免大量的重复计算,从而得到多项式