经典动态规划之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背包的主要内容,如果未能解决你的问题,请参考以下文章