经典动态规划之01背包

Posted 超级码厉

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了经典动态规划之01背包相关的知识,希望对你有一定的参考价值。

reference: cui tian yi                            


1.1 题目

有 N 件物品和一个容量为 V 的背包。放入第 i 件物品占用的容量是 Ci, 得到的价值是 Wi。求解将哪些物品装入背包可使价值总和最大。


1.2 基本思路

这是最基础的背包问题,特点是: 每种物品仅有一件,可以选择放或不放。

用子结构定义状态:即 F [i, v] 表示前 i 件物品恰放入一个容量为 v 的背包可以获得的最大价值。

则其状态转移方程便是: F[i,v] = max{F[i − 1,v],F[i − 1,v − Ci] + Wi}

详细解释:

(1)“将前 i 件物品放入容量为 v 的背包中”这个子问题,若只考虑第 i 件物品的策略(放或不放),那么就可以转化为一个只和前 i − 1 件物品相关的问题。

(2)如果不放第 i 件物品,那么问题就转化为“前 i − 1 件物品放入容量为 v 的背 包中”,价值为 F [i − 1, v];

(3)如果放第 i 件物品,那么问题就转化为“前 i − 1 件物品放 入剩下的容量为v−Ci 的背包中”,此时能获得的最大价值就是F[i−1,v−Ci]再加上 通过放入第 i 件物品获得的价值 Wi。


1.3 java实现

package com.algrithm.onehundred;
public class BackPack01 {  public int backPack01(int capacity, int[] volume , int[] value) {    int number = volume.length;    int[][] f = new int[number + 1][capacity + 1];
    for (int i = 1; i < number + 1 ; i++) {        for (int j = 1; j < capacity + 1; j++) {            // 第i个物品体积大于背包的体积,表示装不下,物品不能放进去          if (volume[i-1] > j) {              f[i][j] = f[i - 1][j];           } else {              f[i][j] = Math.max(f[i - 1][j], f[i - 1][j - volume[i - 1]] + value[i - 1]);           }          }      }      return f[number][capacity]; }
  public static void main(String[] args) {      BackPack01 bp = new BackPack01();      int capacity = 12;      int[] volume = {3,5,2,6,4};      int[] value = {1,1,1,1,1};      int max = bp.backPack01(capacity, volume, value);      System.out.println("max = " + max);   }}


1.4 你还能优化空间吗?

欢迎进群讨论交流:




以上是关于经典动态规划之01背包的主要内容,如果未能解决你的问题,请参考以下文章

动态规划之01背包详解解题报告

动态规划之01背包问题(最易理解的讲解)

:初出茅庐初级篇 - 2.3 动态规划

第 2 章:初出茅庐初级篇 - 2.3 动态规划

动态规划之01背包问题(含代码C)

动态规划-第二节:动态规划之背包类型问题