算法设计分析——多背包问题(java)

问题描述

       多背包问题(MultiplePack):有N种物品和一个容量为V的背包。第i种物品最多有n[i]件可用,每件费用是c[i],价值是w[i]。求解将哪些物品装入背包可使这些物品的费用总和不超过背包容量,且价值总和最大。

  • 是0-1背包问题的延伸,与0-1背包问题的不同点在于把一个背包换成了多个背包,大致意思是有一堆物品放入n个背包中,要使其价值最大,应该怎么放。

  • 这个问题进一步延伸是不考虑n个背包价值最大化,而是要使得n各背包的价值尽可能相同。

详见:(http://www.wutianqi.com/?p=539)

解决方案

因为对于第i种物品有n[i]+1种策略:取0件,取1件……取n[i]件。令f[i][v]表示前i种物品恰放入一个容量为v的背包的最大权值,则有状态转移方程:

f[i][v]=max

将其转换为01背包,普通的转换对于数量较多时,则可能会超时,可以转换成二进制,对于普通的,就是多了一个中间的循环,把j=0~bag[i],表示把第i中背包从取0件枚举到取bag[i]件。

核心代码

public static void multiplePack(int cost,int weight,int amount) {
        if(cost * amount >= V) {
            completePack(cost, weight);
            return;
        }
        int k = 1;
        while(k < amount) {
            zeroOnePack(k * cost, k * weight);
            amount -= k;
            k *= 2;
        }
        zeroOnePack(amount * cost, amount * weight);
}
 
public static void completePack(int cost,int weight) {
        for(int j = cost; j <= V; j++) {
            f[j] = Math.max(f[j], f[j-cost] + weight);
        }
}
 
public static void zeroOnePack(int cost,int weight) {
        for(int j = V; j >= cost; j--) {
            f[j] = Math.max(f[j], f[j-cost] + weight);
        }
}

全部代码在:https://gitee.com/KSRsusu/arithmetic/tree/master/src/multiKnapsack

输入输出示例

posted @ 2021-03-24 16:18  苏洬  阅读(730)  评论(0编辑  收藏  举报