多重背包(小明的背包3)

简介: 多重背包(小明的背包3)

题目

小明有一个容量为 V 的背包。

这天他去商场购物,商场一共有 N 种物品,第 i 种物品的体积为 wi ,价值为 vi ,数量为 si。

小明想知道在购买的物品总体积不超过 V的情况下所能获得的最大价值为多少,请你帮他算算。

**输入描述:

输入第 1 行包含两个正整数 N,V,表示商场物品的数量和小明的背包容量。

第2∼N+1 行包含 3 个正整数 w,v,s,表示物品的体积和价值。

1<N≤10^2, 1<V<2 ×10^2, 1 ≤wi, vi,Si ≤ 2× 10^2。

**输出描述:

输出一行整数表示小明所能获得的最大价值。

**输入输出样例

示例:

**输入

3 30

1 2 3

4 5 6

7 8 9

**输出

39

运行限制

最大运行时间:1s

最大运行内存: 256M

题解

解题思路:

由于每个物品的总数量 * 总体积不确定,所以我们必须对对每个物品进行单独分析:

对于当前分析的该种物品,如果其(数量*体积)>(背包的总容量), 则当做完全背包来处理,

否则,

将该物品的进行二进制拆分,(二进制优化的大概思想是:一个数可以拆分为多个"2的某次方" + “一个常数c”,通过组合这些拆分出来的数,同样可以在dp的过程中组合出所有的可能数,这就避免了从1~n这样去枚举每一种情况,从而降低时间复杂度),将拆分出的不同数量的同种物品看作为一种新物品,然后将这种新物品按01背包的方式进行处理(这里用的是降维的01背包,即滚动数组)。

代码如下(Java):

import java.io.*;
public class Main {
    static int N = 1005;
    static int M = 2005;
    static int n, m;
    static int[] dp = new int[M];
    static int[] w = new int[N];
    static int[] v = new int[N];
    static int[] num = new int[N];
    static BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
    public static void main(String[] args) throws IOException {
        String[] firstLine = br.readLine().split(" ");
        m = Integer.parseInt(firstLine[0]);
        n = Integer.parseInt(firstLine[1]);
        for (int i = 1; i <= m; i++) {
            String[] nextLine = br.readLine().split(" ");
            w[i] = Integer.parseInt(nextLine[0]);
            v[i] = Integer.parseInt(nextLine[1]);
            num[i] = Integer.parseInt(nextLine[2]);
        }
        for (int i = 1; i <= m; i++)
            MultiplePack(w[i], v[i], num[i]);
        System.out.println(dp[n]);
    }
    static void MultiplePack(int weight, int value, int number) {
        if (number * weight > n) CompletePack(weight, value);
        else {
            int k = 1;
            while (k <= number) {
                ZeroOnePack(k * weight, k * value);
                number -= k;
                k = k << 2;
            }
            if (number != 0) ZeroOnePack(number * weight, number * value);
        }
    }
    static void ZeroOnePack(int weight, int value) {
        for (int i = n; i >= weight; i--)
            dp[i] = Math.max(dp[i], dp[i - weight] + value);
    }
    static void CompletePack(int weight, int value) {
        for (int i = weight; i <= n; i++)
            dp[i] = Math.max(dp[i], dp[i - weight] + value);
    }
}

总结

背包问题是动态规划的一种常见考法,我们不仅要学会01和完全背包,还要灵活运用,来解决多重背包的问题。

文章粗浅,希望对大家有帮助!

相关文章
|
8月前
多重背包问题
多重背包问题
68 0
|
3月前
|
算法 决策智能
初谈背包问题——01背包
初谈背包问题——01背包
|
7月前
|
存储 JavaScript 算法
【背包问题】01背包问题和完全背包问题的模板
【背包问题】01背包问题和完全背包问题的模板
|
8月前
01背包和完全背包
01背包和完全背包
|
8月前
|
存储 人工智能 算法
背包问题:小红不想做完全背包
背包问题:小红不想做完全背包
48 1
小明的背包2-动态规划
小明的背包2-动态规划
118 0
|
测试技术 容器
动态规划之背包问题——背包三讲(01背包,完全背包,多重背包)(三)
动态规划之背包问题——背包三讲(01背包,完全背包,多重背包)(三)
243 0
动态规划之背包问题——背包三讲(01背包,完全背包,多重背包)(三)
背包问题——01背包|完全背包 2
背包问题——01背包|完全背包
209 0
|
算法 决策智能
背包问题——01背包|完全背包 1
背包问题——01背包|完全背包
342 0