Code10 特殊背包问题

179 阅读1分钟

题目描述

  • 背包容量为w,
  • 一共有n袋零食,第i袋零食的体积为v[i]
  • 总体积不超过背包容量的情况下,一共有多少种零食的放法? (一个也不放也是一种放法)

code

public class Code10 {
    /**
     * 暴力递归
     */
    public static int snacksWays1(int[] v, int w) {
        if (v == null || v.length <= 0 || w <= 0) {
            return 0;
        }
        return snacksWays1(v, 0, w);
    }

    /**
     * @param v     体积数组
     * @param index 当前位置
     * @param rest  背包剩余容量
     */
    private static int snacksWays1(int[] v, int index, int rest) {
        if (rest < 0) {
            return 0;
        }
        // 当前已经来到了最后的位置 并且背包容量没有越界
        if (index == v.length) {
            return 1;
        }
        // 要当前零食
        var yes = snacksWays1(v, index + 1, rest - v[index]);
        // 不要当前零食
        var no = snacksWays1(v, index + 1, rest);
        return yes + no;
    }

    /**
     * 暴力递归 -> 动态规划
     */
    public static int snacksWays2(int[] v, int w) {
        if (v == null || v.length <= 0 || w <= 0) {
            return 0;
        }
        int[][] dp = new int[v.length][w];
        int N = dp.length;
        int M = dp[0].length;
        // 填充最后一行
        for (int i = 0; i < M; i++) {
            dp[N - 1][i] = 1;
        }
        for (int i = N - 2; i >= 0; i--) {
            for (int j = M - 1; j >= 0; j--) {
                // j - v[i] >= 0 不越界
                dp[i][j] = dp[i + 1][j] + (j - v[i] >= 0 ? dp[i + 1][j - v[i]] : 0);
            }
        }
        return dp[0][w - 1];
    }

    public static void main(String[] args) {
        int[] arr = {4, 3, 2, 9};
        int w = 8;
        System.out.println(snacksWays1(arr, w));
        System.out.println(snacksWays2(arr, w));
    }
}