完全背包

来源:互联网 发布:python return{} 编辑:程序博客网 时间:2024/06/04 23:20

完全背包和01背包的区别

01背包:有n个物品,每种物品只能被使用一次

完全背包:有n个物品,每个物品可以被多次使用

完全背包的递推公式可以由01背包的递推公式扩展得到(如果背包可以装下k个weight[i])
二维:
dp[i][j] = Math.max(dp[i-1][j], dp[i-1][j-k*weight[i]] + k*value[i])
一维
dp[j] = Math.max(dp[j],dp[j-k*weight[i]]+k*value[i])
当可以放入第i件物品的时候,要尽可能多的装入第i件物品
二维代码:

import java.util.Scanner;public class Wanquanbeibao {    static int[][] dp;    public static void main(String[] args) {        Scanner in = new Scanner(System.in);        int n = in.nextInt();        int m = in.nextInt();        int[] value = new int[n+1];        int[] weight = new int[n+1];        for (int i = 1; i <= n; i++) {            value[i] = in.nextInt();            weight[i] = in.nextInt();        }        dp = new int[n+1][m+1];        for (int i = 1; i <= n; i++) {            for (int j = 1; j <= m; j++) {                for (int k = 0; k*weight[i] <= j; k++) {                    dp[i][j] = Math.max(dp[i-1][j], dp[i-1][j-k*weight[i]]+k*value[i]);                }            }        }        System.out.println(dp[n][m]);    }}

一维代码:

import java.util.Scanner;public class Wanquanbeibao1 {    static int[] dp;    public static void main(String[] args) {        Scanner in = new Scanner(System.in);        int n = in.nextInt();        int m = in.nextInt();        int[] value = new int[n+1];        int[] weight = new int[n+1];        for (int i = 1; i <= n; i++) {            value[i] = in.nextInt();            weight[i] = in.nextInt();        }        dp = new int[m+1];        for (int i = 1; i <= n; i++) {            //与01背包不同的是j的循环是从1到m            for (int j = 1; j <= m; j++) {                for (int k = 0; k*weight[i] <= j; k++) {                    dp[j] = Math.max(dp[j], dp[j-k*weight[i]]+k*value[i]);                }            }        }        System.out.println(dp[m]);    }}

之前看到一个大牛写的很简洁的完全背包的一维代码,移步大牛代码
大牛的代码思路是不论同一个物品装入多少次,都是一次装入一个,所以问题转换成在装入第i个物品之后继续装第i种物品,以下将大神的c代码转为java代码

import java.util.Scanner;public class Wanquanbeibao2 {    static int[] dp;    public static void main(String[] args) {        Scanner in = new Scanner(System.in);        int n = in.nextInt();        int m = in.nextInt();        int[] value = new int[n+1];        int[] weight = new int[n+1];        for (int i = 1; i <= n; i++) {            value[i] = in.nextInt();            weight[i] = in.nextInt();        }        dp = new int[m+1];        for (int i = 1; i <= n; i++) {            for (int j = 1; j <= m; j++) {//与01背包唯一的不同点                if(j >= weight[i])                    dp[j] = Math.max(dp[j], dp[j-weight[i]]+value[i]);            }        }        System.out.println(dp[m]);    }}

与01背包的不同仅仅是j的遍历方向。