• 算法设计分析——多背包问题(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{f[i-1][v-k*c[i]]+k*w[i]|0<=k<=n[i]}

    将其转换为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

    输入输出示例

  • 相关阅读:
    为什么今天的L4无人驾驶无法到达终局(转)
    各种卷积类型Convolution
    关于快速、深入理解需求
    测试注意事项及工作标准
    测试工作指引
    测试验收工作指引
    Jmeter的json提取器使用
    高等数学:第一章 函数与极限
    vscode
    Python模块查找路径
  • 原文地址:https://www.cnblogs.com/Monster-su/p/14573999.html
Copyright © 2020-2023  润新知