动态规划-01背包问题

2021-02-17  本文已影响0人  狼爷的号

更多文章,可关注我的 博客园掘金

01背包

01背包问题

有N件物品和一个容量为V的背包。第i件物品的体积是c[i],价值是w[i]。求解将哪些物品装入背包可使价值总和最大。
从这个题目中可以看出,01背包的特点就是:每种物品仅有一件,可以选择放或不放。
其状态转移方程是:

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

填表

要理解上面的那个公式,需要学会填表。
假设

n=5, C=13, w={4,5,4,3,10}, v={9,10,9,2,24}
image

公式说明

image

假如背包要放第i件物品,
此时如果不放第i件物品,那么问题就转化为“前i-1件物品放入重量是w的背包中”,价值为f[i-1,j];
如果放第i件物品,那么问题就转化为“前i-1件物品放入剩下的重量为j-Wi的背包中”,此时能获得的最大价值就是f[i-1,j-Wi]再加上通过放入第i件物品获得的价值Pi,此时只要比较f[i-1,j]和f[i-1,j-Wi]+Pi那个大就能获取到背包里最大的价值是多少了。

代码

public class Test {
    public static int getMaxValue(int[] weight, int[] value, int w, int n) {
        // 创建一个二维数组,横列是物品的价值,竖列是物品的重量
        int[][] table = new int[n + 1][w + 1];
        for (int i = 1; i <= n; i++) { //物品
            for (int j = 1; j <= w; j++) {  //背包大小
                if (weight[i] > j) {
                    //当前物品i的重量比背包容量j大,装不下,肯定就是不装
                    table[i][j] = table[i - 1][j];
                } else {
                    //装得下,Max{装物品i, 不装物品i}
                    table[i][j] = Math.max(table[i - 1][j], table[i - 1][j - weight[i]] + value[i]);
                }
            }
        }
        return table[n][w];
    }

    public static void main(String[] args) {
        int n = 5, w = 13;                //物品个数,背包容量
        int[] value = {0,9,10,9,2,24};    //各个物品的价值
        int[] weight = {0,4,5,4,3,10};    //各个物品的重量
        System.out.println(getMaxValue(weight, value, w, n));
    }
}

参考资料

上一篇 下一篇

猜你喜欢

热点阅读