多重背包问题I

题目来源
多重背包问题I_第1张图片
多重背包问题即每种物品可以使用的次数有限,如果为1次就是01背包问题,如果为无限次就是完全背包问题。

分析
完全背包问题,如下
因为可以使用无限次,所以k的约束条件为:k*v[i]<=j

for(int i = 1;i <= 物品种数;i++){
	for(int j = 1;j <= 背包总体积;j++){
		for(int k = 0;k*v[i]<=j;k++){
			dp[i][j] = Math.max(dp[i-1][j]+dp[i-1][j-k*v[i]]+w[i]);
		}
	}
}

对于本题,第i种物品使用次数为s[i]
因此约束条件改为k <= s[i]&&k*v[i]<=j

具体代码

import java.util.Scanner;

public class Main{
    public static void main(String[] args){
        Scanner sc = new Scanner(System.in);
        int m = sc.nextInt();
        int n = sc.nextInt();
        int[] v = new int[m+1];
        int[] w = new int[m+1];
        int[] s = new int[m+1];
        int[][] dp = new int[m+1][n+1];
        for(int i = 1;i <= m;i++){
            v[i] = sc.nextInt();
            w[i] = sc.nextInt();
            s[i] = sc.nextInt();
        }
        for(int i = 1;i <= m;i++){
            for(int j = 1;j <= n;j++){
                dp[i][j] = dp[i-1][j];
                for(int k = 0;k <= s[i];k++){
                    if(k*v[i]<=j)
                        dp[i][j] = Math.max(dp[i][j],dp[i-1][j-k*v[i]]+k*w[i]);
                }
            }
        }
        System.out.println(dp[m][n]);
    }
}

时间复杂度: O(mnk)
空间复杂度: O(m*n)

优化
状态转移方程

dp[i][j] = Math.max(dp[i-1][j],dp[i-1][j-k*v[i]]+k*w[i])

令j从大到小遍历,可以简化为

dp[j] = Math.max(dp[j],dp[j-k*v[i]]+k*w[i])

具体代码

import java.util.Scanner;

public class Main{
    public static void main(String[] args){
        Scanner sc = new Scanner(System.in);
        int m = sc.nextInt();
        int n = sc.nextInt();
        int[] v = new int[m+1];
        int[] w = new int[m+1];
        int[] s = new int[m+1];
        int[] dp = new int[n+1];
        for(int i = 1;i <= m;i++){
            v[i] = sc.nextInt();
            w[i] = sc.nextInt();
            s[i] = sc.nextInt();
        }
        for(int i = 1;i <= m;i++){
            for(int j = n;j >= 0;j--){
                dp[j] = dp[j];
                for(int k = 0;k <= s[i];k++){
                    if(k*v[i]<=j)
                        dp[j] = Math.max(dp[j],dp[j-k*v[i]]+k*w[i]);
                }
            }
        }
        System.out.println(dp[n]);
    }
}

时间复杂度: O(mnk)
空间复杂度: O(n)

你可能感兴趣的:(背包问题)