经典算法题04-动态规划算法(背包问题)

原创 2016年05月31日 10:29:23

本来我是想解决公共最长子序列问题,但是在解题过程中需要先清楚动态规划算法,故先用动态规划算法中最经典的背包问题来说明。

背包问题

问题描述

有N件物品和一个容量为V的背包,第i件物品的费用是c[i],价值是w[i],求解将哪些物品装入背包可使这些物品的费用总和不超过背包容量,且价值总和最大?

实际生活中的例子可以描述为小偷拿个袋子去偷东西,拿下图中的哪些东西装满背包才能获取最大价值?

这个问题的特点是:每种物品只有一件,可以选择放或者不放。
这里写图片描述
我们把题目具体下:

有3个商品,背包的体积为10,他们的体积为c[]={3,4,5}; 价值为 w={4,5,6}。V=10,N=3,c[]={3,4,5}, w={4,5,6}

从转移方程上可以看出,前i个物品的最优解只依赖于前i-1个物品最优解,而与前i-2,i-3,…各物品最优无直接关系,可以利用这个特点优化存储空间,即只申请一个一维数组即可,算法时间复杂度(O(VN))为:

for i=1..N

  for v=V..0

    f[v]=max{f[v],f[v-c[i]]+w[i]};

注意v的遍历顺序!!!
下面几种背包用到类似优化,以后不再赘述。

分析

在求最优解的背包问题中,一般有两种不同的问法:1、要求“恰好装满背包”时的最优解;2、求小于等于背包容量的最优解,即不一定恰好装满背包。

这两种问法,在初始化的时候是不同的。
(1)背包不一定装满

这里写图片描述
(2)背包一定装满
注意初始值,其中-inf表示负无穷:
这里写图片描述
这是最基础的背包问题,特点是:每种物品仅有一件,可以选择放或不放。可以将背包问题的求解看作是进行一系列的决策过程,即决定哪些物品应该放入背包,哪些不放入背包。

如果一个问题的最优解包含了物品n,即Xn = 1,那么其余X1, X2, …..,Xn-1
一定构成子问题1,2,…..,n-1在容量C - cn时的最优解。如果这个最优解不包含物品n,即Xn = 0;
那么其余 X1, X2…..Xn-1一定构成了子问题 1,2,….n-1在容量C时的最优解。 //请各位仔细品味这几句话

根据以上分析最优解的结构递归定义问题的最优解: f[i][v] = max{ f[i-1][v] , f[i-1][v - c[i]] + v[i]}

编码


import java.io.IOException;

/**
 * @param
 * @Title: 动态规划-背包问题
 * @Author: xuming
 * @Description:
 * @date:2016/5/31 9:22
 * @return
 */
public class myMathDemo2 {

    public static void main(String[] args) throws IOException {

        int c[] = {0, 3, 4, 5};
        int v[] = {0, 4, 5, 6};
        int f[][] = new int[4][11];

        for (int i = 1; i < 4; i++)
            for (int j = 1; j < 11; j++) {
                if (c[i] > j)//如果背包的容量,放不下c[i],则不选c[i]
                    f[i][j] = f[i - 1][j];
                else {
                    f[i][j] = Math.max(f[i - 1][j], f[i - 1][j - c[i]] + v[i]);//转移方程式
                    System.out.println(f[i][j]);
                }
            }
        System.out.println("last answer: " + f[3][10]);
        for (int m = 0; m < 4; m++) {
            for (int n = 0; n < 11; n++) {
                System.out.println("the matrix answer f[" + m + "][" + n + "]:" + f[m][n]);
            }
        }


    }


}

结果是:
这里写图片描述

版权声明:本文为博主原创文章,转载请注明http://blog.csdn.net/mingzai624。

相关文章推荐

背包算法研究

背包算法问题描述假定背包的最大容量为W,N件物品,每件物品都有自己的价值和重量,将物品放入背包中,使得背包内物品的总价值最大。有这样一个场景——小偷在屋里偷东西,他带着一只背包,屋子里物品数量有限——...

【数据结构_动态规划_背包问题_0963】小偷的背包

通过递归找到当前最优解然后回朔; #include #include using namespace std; int bag[1005]; int dongtaiguihua(int ...

linux shell 将多行文件转换为一行

说实话,虽然对shell编程包括awk有所了解,但是对sed的多行与一行的处理还是不甚理解,在网上搜罗了一篇文章觉得还不错,记录一下:     今天一个工程师问我,怎么将一个文件中的...
  • hjxhjh
  • hjxhjh
  • 2013年12月11日 16:27
  • 27266

kruskal算法,动态规划,背包问题

  • 2013年12月09日 14:46
  • 239KB
  • 下载

【动态规划法】解析经典算法题Two eggs problem及其延伸问题

【动态规划法】解析经典算法题Two eggs problem及其延伸问题Two eggs problem可以说是互联网面试中老生常谈的算法题了,经常可以在各大互联网公司的笔试真题中看到它的各类变种(腾...

每天一道算法题(一) (动态规划算法)背包问题Java实现

动态规划 动态规划在wiki上的定义: dynamic programming is a method for solving a complex problem by breaking it...

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

  • 2012年01月04日 15:18
  • 394KB
  • 下载
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:经典算法题04-动态规划算法(背包问题)
举报原因:
原因补充:

(最多只允许输入30个字)