动态规划- 01 背包问题

132 阅读1分钟

动态规划- 01 背包问题

  • 给定一个承重量为C的背包,n个重量分别为w1,w2,w3,w5....的物品,物品i放入背包能产生pi(>0)的价值(i=1,2,...,n)。
  • 每个物品要么整个放入背包,要么不放。要求找出最大价值的装包方案。
  • 输入格式:
  • 输入的第一行包含两个正整数n和C(1≤n≤20),
  • 第二行含n个正整数分别表示n个物品的重量,
  • 第三行含n个正整数分别表示n个物品放入背包能产生的价值。
  • 输出格式:
  • 在一行内输出结果,包括最大价值装包方案的价值、具体装包方案,用空格隔开。具体装包方案是n个物品的一个子集,用长度为n的0、1串表示(1表示对应物品被选中,0表示没有被选中)。如果这样的0、1串不唯一,取字典序最大的那个串。

输入样例: 4 9 2 3 4 5 3 4 5 7

输出样例: 12 1110

public static void main(String[] args) {
    Scanner sc = new Scanner(System.in);
    String input1 = sc.nextLine();
    String[] split1 = input1.split(" ");
    //物品数量
    int n = Integer.parseInt(split1[0]);
    //承重量
    int bagWeight = Integer.parseInt(split1[1]);
    //物品重要
    int[] weight = Arrays.stream(sc.nextLine().split(" ")).mapToInt(Integer::parseInt).toArray();
    //物品价值
    int[] value = Arrays.stream(sc.nextLine().split(" ")).mapToInt(Integer::parseInt).toArray();

    int[] result = new int[bagWeight + 1];

    for (int i = 0; i <= bagWeight; i++) {
        if (i >= weight[0]) {
            result[i] = value[0];
        } else {
            result[i] = 0;
        }
    }

    for (int i = 1; i < n; i++) {
        int[] next = new int[bagWeight + 1];
        for (int j = 0; j <= bagWeight; j++) {
            if (j >= weight[i]) {
                // 公式:max(选i这件物品价值,不选i这件物品的价值) Math.max(value[i]+result[j-weight[i]],result[j])
                next[j] = Math.max(value[i]+result[j-weight[i]],result[j]);
            }else{
                next[j]= result[j];
            }
        }
        result = next;
    }

    System.out.println(result[bagWeight]);
}