zoukankan      html  css  js  c++  java
  • 算法设计分析——多背包问题(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

    输入输出示例

  • 相关阅读:
    Unix下5种I/O模型
    UDP/TCP拾遗
    智能指针
    YUV的数据格式
    OpenCV中RGB和HSV转换的问题
    RGB、YUV和HSV颜色空间模型
    const成员函数和mutable关键字
    设计模式--观察者模式Observer(对象行为型)
    linux备忘簿
    ctags使用详解(转载)
  • 原文地址:https://www.cnblogs.com/Monster-su/p/14573999.html
Copyright © 2011-2022 走看看