多重背包问题II

多重背包问题II
 总体积是m,每个小物品的体积是A[i] ,每个小物品的数量是B[i],每个小物品的价值是C[i]

求能够放入背包内的最大物品能够获得的最大价值

和上一个很类似

上一题体积就是价值,这里的价值是单独定义了

状态转移方程

不放A[i]

f[i][j] =f[i-1][j]

放A[j]

可放多个设为k,

k = min(j/A[i],B[i])

f[i][j] = f[i-1][j- ki*A[i]] + ki*C[i] 0<=ki<=k 取最大值

完全背包问题时候:0<=ki*A[i]<=m

public class Solution {
    public int backPack(int m, int[] A,int[] B ,int[] C) {
        // write your code here
        int[] P = new int[m+1];// P[i][j] 前i个物品放在j的空间中的最大价值
        for(int i = 0;i< A.length; i++){
            for(int j = m;j>=1;j--){
                if(j>=A[i]){
                    int k = j/A[i];// 该物品最大可以放k个,然而限制条件最大是B[i]
                    k = Math.min(k,B[i]);// 取最小值
                    while(k>=0){
                        if(j>=A[i]*k){
                            P[j] =Math.max(P[j], P[j-k*A[i]] + k*C[i]);
                        }
                        k--;
                    }
                }

                else
                    P[j] = Math.max(P[j],P[j]);
            }
        }
        return P[m];
    }
    /**
     * 多重背包问题
     * 总体积是m,每个小物品的体积是A[i] ,每个小物品的数量是B[i]
     *
     * @param m: An integer m denotes the size of a backpack
     * @param A: Given n items with size A[i] 0 开始的 A是
     * @return: The maximum size
     */
    public int backPack1(int m, int[] A,int[] B ,int[] C) {
        // write your code here
        int[][] P = new int[A.length+1][m+1];// P[i][j] 前i个物品放在j的空间中的最大价值
        for(int i = 0;i< A.length; i++){
            for(int j = m;j>=1;j--){
                if(j>=A[i]){
                    int k = j/A[i];// 该物品最大可以放k个,然而限制条件最大是B[i]
                    k = Math.min(k,B[i]);// 取最小值
                    while(k>=0){
                        if(j>=A[i]*k){
                            P[i+1][j] =Math.max(P[i+1][j], P[i][j-k*A[i]] + k*C[i]);
                        }
                        k--;
                    }
                }

                else
                    P[i+1][j] = Math.max(P[i][j],P[i+1][j]);
            }
        }
        return P[A.length][m];
    }
    public static void main(String[] args){
        int m = 10;//100;//
        int[] A=new int[]{1,2,3,4};
        int[] B=new int[]{2,3,1,4};
        int[] C=new int[]{2,13,4,2};
        int sum = new Solution().backPack(m, A,B,C);
        System.out.println(sum);
    }
}

10:45

100:55

时间: 2024-10-11 03:44:09

多重背包问题II的相关文章

O(V*n)的多重背包问题

多重背包问题: 有n件物品,第i件价值为wi,质量为vi,有c1件,问,给定容量V,求获得的最大价值. 朴素做法: 视为0,1,2,...,k种物品的分组背包 [每组只能选一个] f[i][j]=Max(f[i][j-k*v[i]]+k*w[i]) 但是i,j,k都要枚举,复杂度为 n*V*k 朴素做法的改进: 因为发现用二进制可以表示1..k之内的所有数 [整数二进制打开后为01串,所以可以被二进制表示] 所以将k个物品拆分成1,2,4...2^m,k-2^m   ( 其中2^m<=k<2^

多重背包问题(来源:背包九讲)

问题: 有N种物品和一个容量为V的背包.第i种物品最多有n[i]件可用,每件费用是c[i],价值是w[i].求解将哪些物品装入背包可使这些物品的费用总和不超过背包容量,且价值总和最大. 基本算法: 这题目和全然背包问题非常类似.主要的方程仅仅需将全然背包问题的方程稍微一改就可以,由于对于第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

【动态规划/多重背包问题】POJ1014-Dividing

多重背包问题的优化版来做,详见之前的动态规划读书笔记. dp[i][j]表示前i中数加得到j时第i种数最多剩余几个(不能加和得到i的情况下为-1)递推式为: dp[i][j]=mi(dp[i-1][j]≥0,即前i-1种数就能达到数字j) =-1(j<ai 或者 dp[i][j-ai]≤0,即再加上一个第i种数也无法达到j 或者 当前和小于当前数) =dp[i][j-ai]-1(可以达到的情况) #include<iostream> #include<cstdio> #inc

C语言-多重背包问题

多重背包问题 问题:有N种物品和一个容量为V的背包.第i种物品最多有n[i]件可用,每件费用是c[i],价值是w[i].求解将哪些物品装入背包可使这些物品的费用总和不超过背包容量,且价值总和最大. 分析: 这题目和完全背包问题很类似.基本的方程只需将完全背包问题的方程略微一改即可,因为对于第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

动态规划-多重背包问题

0-1背包问题 完全背包问题 多重背包问题是0-1背包问题和完全背包问题的综合体,可以描述如下:从n种物品向容积为V的背包装入,其中每种物品的体积为w,价值为v,数量为k,问装入的最大价值总和? 我们知道0-1背包问题是背包问题的基础,所以在解决多重背包问题的时候,要将多重背包向0-1背包上进行转换.在多重背包问题中,每种物品有k个,可以将每种物品看作k种,这样就可以使用0-1背包的算法.但是,这样会增加数据的规模.因为该算法的时间复杂度为O(V*∑ni=1ki),所以要降低每种物品的数量ki.

HDU ACM 2191 悼念512汶川大地震遇难同胞——珍惜现在,感恩生活-&gt;多重背包问题

分析:多重背包问题.这里直接转换为01背包,为使用二进制. #include<iostream> using namespace std; int price[101]; int weight[101]; int number[101]; int dp[101]; int main() { int C,n,m; int i,j,k; cin>>C; while(C--) { cin>>n>>m; for(i=0;i<m;i++) { cin>&g

【动态规划】简单背包问题II

问题 B: [动态规划]简单背包问题II 时间限制: 1 Sec  内存限制: 64 MB提交: 21  解决: 14[提交][状态][讨论版] 题目描述 张琪曼:“为什么背包一定要完全装满呢?尽可能多装不就行了吗?” 李旭琳:“你说得对,这和墨老师曾告诉我们的‘日中则昃,月满则亏’是一个道理.”所以,现在的问题是,她们有一个背包容量为v(正整数,0≤v≤20000),同时有n个魔法石(0≤n≤30),每个魔法石有一个体积 (正整数).要求从n个魔法石中,任取若干个装入包内,使背包的剩余空间为最

动态规划第二讲——完全背包与多重背包问题

上一节,我们讨论了01背包问题,说明了*递归与分治法 与 动态规划DP的区别和联系,介绍了缓存的概念*.以下,我们用DC.DP.cache分别表示分治法.动态规划和缓存.本节,我们讨论01背包的另外两种形似-- 完全背包和多重背包问题,分析DP问题的另外一些情况. 例一:完全背包问题 同样有n种价值和重量分别为weight[i] and value[i], 背包大小W.限制条件:每种物品数目是无限的.问:能挑选出来的总价值最大的物品组合总重量? 分析一:这里,我们无视数量有限这个条件,可以得到下

poj 1742 多重背包问题 dp算法

题意:硬币分别有 A1.....An种,每种各有C1......Cn个,问组成小于m的有多少种 思路:多重背包问题 dp[i][j]表示用前i种硬币组成j最多剩下多少个  dp=-1的表示凑不齐 dp[0][0]=0; for(int i=0;i<n;i++)     for(int j=0;j<=m;j++) {    if(dp[i][j]>=0)   dp[i+1][j]=c[i];  //表示用前i种可以凑齐j元,自然就全部剩下了       else if(j<a[i]|