背包

01背包

public static void zeroOne(int[] weight, int[] value, int capacity){
    dp = new int[capacity + 1];
    for (int i = 0; i < weight.length; i++) {
        for (int j = capacity; j >= weight[i]; j--) {
            if (j - weight[i] >= 0) {
                dp[j] = Math.max(dp[j], dp[j - weight[i]] + value[i]);
            }
        }
    }
}

完全背包

public static void complete(int[] weight, int[] value, int capacity){
    dp = new int[capacity + 1];
    for (int i = 0; i < weight.length; i++) {
        for (int j = weight[i]; j <= capacity; j++) {
            dp[j] = Math.max(dp[j - weight[i]] + value[i], dp[j]);
        }
    }
}

多重背包

public static void multi(int[] weight, int[] value, int[] nums, int capacity){
    dp = new int[capacity + 1];
    for (int i = 0; i < weight.length; i++) {
        for (int j = capacity; j >= weight[i]; j--) {
            for (int k = 0; k <= nums[i] && k * weight[i] <= j; k++) {
                dp[j] = Math.max(dp[j], dp[j - k * weight[i]] + k * value[i]);
            }
        }
    }
}

多重背包(二进制优化)

public static void main(String[] args) throws IOException {
    BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
    String[] s = br.readLine().split(" ");
    int capacity = Integer.parseInt(s[1]);
    int n = Integer.parseInt(s[0]);

    int[] weight = new int[n * 11];
    int[] val = new int[n * 11];
    int cnt = -1;
    for (int i = 0; i < n; i++) {
        s = br.readLine().split(" ");
        // 二进制优化
        int w = Integer.parseInt(s[0]);
        int v = Integer.parseInt(s[1]);
        int num = Integer.parseInt(s[2]);
        int k = 1;
        while (k <= num){
            cnt++;
            weight[cnt] = w * k;
            val[cnt] = v * k;
            num -= k;
            k *= 2;
        }
        if (num > 0){
            cnt++;
            weight[cnt] = w * num;
            val[cnt] = v * num;
        }
    }

    multi(weight, val, capacity);

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

public static void multi(int[] weight, int[] value, int capacity){
    dp = new int[capacity + 1];

    for (int i = 0; i < weight.length; i++) {
        for (int j = capacity; j >= weight[i]; j--) {
            dp[j] = Math.max(dp[j], dp[j - weight[i]] + value[i]);
        }
    }
}

混合背包

private static void all(int[] weight, int[] value, int[] type, int capacity) {
    dp = new int[capacity + 1];
    for (int i = 0; i < weight.length; i++) {
        // 只能一次,01背包
        if (type[i] == -1) {
            for (int j = capacity; j >= weight[i]; j--) {
                if (j - weight[i] >= 0) {
                    dp[j] = Math.max(dp[j], dp[j - weight[i]] + value[i]);
                }
            }
        // 无限次,完全背包
        }else if (type[i] == 0){
            for (int j = weight[i]; j <= capacity; j++) {
                dp[j] = Math.max(dp[j - weight[i]] + value[i], dp[j]);
            }
        // 有限次,多重背包
        }else {
            for (int j = capacity; j >= weight[i]; j--) {
                for (int k = 0; k <= type[i] && k * weight[i] <= j; k++) {
                    dp[j] = Math.max(dp[j], dp[j - k * weight[i]] + k * value[i]);
                }
            }
        }
    }
}