dp[i] 体积为i时的最大价值
dp[0,…n] = 0;
最大解是dp[n]
dp[0] = 0, dp[1,… n] = -Int_MIN
最大解为max(dp[0,…n]
01背包
01背包物品只能用一次,第二层循环从大到小,因为要用第i-1次的状态
练习:https://www.acwing.com/problem/content/2/
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
int[] dp = new int[1001];
Scanner in = new Scanner(System.in);
int m = in.nextInt();
int n = in.nextInt();
int[] v = new int[m+1];
int[] w = new int[m+1];
for(int i = 1; i <= m; ++i) {
v[i] = in.nextInt();
w[i] = in.nextInt();
}
for(int i = 1; i <= m; ++i) {
for(int j = n; j >= v[i]; j--) {
dp[j] = Math.max(dp[j], dp[j - v[i]] + w[i]);
}
}
System.out.println(dp[n]);
}
}
完全背包
完全背包物品可以用任意次,第二层循环从小到大
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
int[] dp = new int[1001];
Scanner in = new Scanner(System.in);
int m = in.nextInt();
int n = in.nextInt();
int[] v = new int[m+1];
int[] w = new int[m+1];
for(int i = 1; i <= m; ++i) {
v[i] = in.nextInt();
w[i] = in.nextInt();
}
for(int i = 1; i <= m; ++i) {
for(int j = v[i]; j <= n; j++) {
dp[j] = Math.max(dp[j], dp[j - v[i]] + w[i]);
}
}
System.out.println(dp[n]);
}
}
多重背包1
多重背包比01背包多一个限制条件,每个物品最多只能用s次;
第二次循环还是从大到小,第三次循环 选0,…, s次的情况
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
int[] dp = new int[1001];
Scanner in = new Scanner(System.in);
int m = in.nextInt();
int n = in.nextInt();
for(int i = 1; i <= m; ++i) {
int v = in.nextInt(), w = in.nextInt(), s = in.nextInt();
for(int j = n; j >= v; j--) {
for(int k = 0; k * v <= j && k <= s; ++k )
dp[j] = Math.max(dp[j], dp[j