多重背包--java

多重背包

有N种物品和一个容量为V的背包。第i种物品最多有n[i]件可用,每件费用是c[i],价值 是w[i]。求解将哪些物品装入背包可使这些物品的费用总和不超过背包容量,且价值总和最大
母函数的思想也是如此 给你 价值, 物品数量的限制, 然后凑,

hdu2191

第一种写法

import java.util.*;

public class Main {

    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        while (sc.hasNext()) {

            int n = sc.nextInt();
            int m = sc.nextInt();

            int v[] = new int[101];
            int w[] = new int[101];
            int num[] = new int[101];
            for (int i = 0; i < m; i++) {
                v[i] = sc.nextInt();
                w[i] = sc.nextInt();
                num[i] = sc.nextInt();
            }

            int dp[] = new int[10001];
            for (int i = 0; i <= m; i++)
                dp[i] = 0;
            for (int i = 0; i < m; i++) {
                for (int k = 0; k <= num[i]; k++) {
                    for (int j = n; j >= v[i]; j--) {
                        if (dp[j] < dp[j - v[i]] + w[i]) {
                            dp[j] = dp[j - v[i]] + w[i];

                        }
                    }
                }
            }

            System.out.println(dp[n]);
        }
    }
}

 第二种写法:

package demo2;

import java.util.*;

public class Main {
    public static int sum(int []n){
        int sum=0;
        for(int i=0;i<n.length;i++)
            sum+=n[i];
        return sum;
    }
    public static int back(int []a,int []v,int[]n,int m){
            int sum=sum(n);
            int a1[]= new int[sum];
            int v1[]=new int[sum];
            for(int i=0;i<a.length;i++)
                a1[i]=a[i];
            for(int i=0;i<v.length;i++)
                v1[i]=v[i];
            int k= a.length;
            for(int i=0;i<n.length;i++){
                while(n[i]!=1){
                    a1[k]=a[i];
                    v1[k]=v[i];
                    k++;
                    n[i]--;
                }
            }
            int dp[]=new int[m+1];
            for(int i=0;i<a1.length;i++){
                for(int j=m;j>=a1[i];j--){
                    dp[j] = Math.max(dp[j],dp[j-a1[i]]+v1[i]);
                }
            }
            return dp[m];
    }

    public static void main(String[] args) {
        int[] a = {1,2,3};
        int[] v = {2,1,4};
        int[] n = {5,4,2};
        int m = 6;
        int value = back(a,v,n,m);
        System.out.println(value);

    }
}

优化写法:

将多重背包转换为完全背包

     
    public class duochongbeibao1 {
        public static int[] a = {1,2,3};//重量
        public static int[] v = {2,1,4};//价值
        public static int[] n = {5,4,2};//数量
        public static int m = 6;
        public static int back(int[] a,int[] v,int[] n,int m){
            int value = fun(a.length-1,m);
            return value;
        }
        public static int fun(int i,int m){
            if(i == 0)
                return(m/a[i]<n[i]?m/a[i]:n[i])*v[i];
            else{
                int x = (m/a[i]<n[i]?m/a[i]:n[i]) + 1;
                int[] dp = new int[x];
                for(int j = 0;j<x;j++)
                    dp[j] = fun(i-1,m-j*a[i])+j*v[i];
                return max(dp);
            }
        }
        public static int max(int[] dp){
            int index = 0;
            if(dp.length == 0)
                return -1;
            for(int i = 1;i<dp.length;i++){
                if(dp[i]>dp[index])
                    index = i;
            }
            return dp[index];
        }
        public static void main(String[] args) {
            // TODO Auto-generated method stub
            int value = back(a,v,n,m);
            System.out.println(value);
        }
 
    }
原文地址:https://www.cnblogs.com/ls-pankong/p/10490891.html