
import java.util.*;
import java.io.*;
public class Main {
static int[] v;
static int[] w;
static int[][] f;
public static void main(String[] args) {
Scanner sc = new Scanner(new BufferedInputStream(System.in));
int n = sc.nextInt();
int m = sc.nextInt();
v = new int[n + 1];
w = new int[n + 1];
f = new int[n + 1][m + 1];
for (int i = 1 ; i <= n ; i ++) {
v[i] = sc.nextInt();
w[i] = sc.nextInt();
}
for (int i = 1 ; i <= n ; i ++) {
for (int j = 0 ; j <= m ; j ++)
if (j >= v[i])
f[i][j] = Math.max(f[i - 1] [j - v[i]] + w[i] , f[i - 1][j]);
else f[i][j] = f[i - 1][j];
}
System.out.println(f[n][m]);
}
}
- 优化 : 方程决策
f[i][j] = Math.max(f[i -1][j] , f[i - 1][j - v[i]] + w[i]);
- 第
i 层 都是由 i - 1 层 推导而来。这时候就可以用 滚动数组 技巧.
- 当
本层状态由 上层 状态得到的话 需要从大到小枚举。
import java.util.*;
import java.io.*;
public class Main {
static int[] v;
static int[] w;
static int[] f;
public static void main(String[] args) {
Scanner sc = new Scanner(new BufferedInputStream(System.in));
int n = sc.nextInt();
int m = sc.nextInt();
v = new int[n + 1];
w = new int[n + 1];
f = new int[m + 1];
for (int i = 1 ; i <= n ; i ++) {
v[i] = sc.nextInt();
w[i] = sc.nextInt();
}
for (int i = 1 ; i <= n ; i ++) {
for (int j = m ; j >= v[i] ; j --)
f[j] = Math.max(f[j - v[i]] + w[i] , f[j]);
}
System.out.println(f[m]);
}
}


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