🍑 算法题解专栏
🍑 分组背包问题
输入
3 5
2
1 2
2 4
1
3 4
1
4 5
输出
8
👨🏫 参考题解
🍑 终极简化版
import java.util.Scanner;
public class 分组背包极简版
{
static int N = 110;
static int[] f = new int[N];
static int[] v = new int[N];
static int[] w = new int[N];
public static void main(String[] args)
{
Scanner sc = new Scanner(System.in);
int n = sc.nextInt();
int m = sc.nextInt();
for (int i = 0; i < n; i++)
{
int s = sc.nextInt();
for (int j = 1; j <= s; j++)
{
v[j] = sc.nextInt();
w[j] = sc.nextInt();
}
for (int j = 1; j <= s; j++)// 枚举物品
for (int k = m; k >= v[j]; k--)// 枚举体积
f[k] = Math.max(f[k], f[k - v[j]] + w[j]);
}
System.out.println(f[m]);
}
}
🍑 滚动数组优化
import java.util.Scanner;
public class Main
{
static int N = 110;
static int[] f = new int[N];
static int[][] v = new int[N][N];
static int[][] w = new int[N][N];
static int[] s = new int[N];
public static void main(String[] args)
{
Scanner sc = new Scanner(System.in);
int n = sc.nextInt();
int m = sc.nextInt();
for (int i = 1; i <= n; i++)
{
s[i] = sc.nextInt();
for (int j = 1; j <= s[i]; j++)
{
v[i][j] = sc.nextInt();
w[i][j] = sc.nextInt();
}
}
for (int i = 1; i <= n; i++)// 枚举每一组
for (int j = m; j >= 1; j--)// 枚举体积(体积从大到小枚举【后边依赖于前边的】)
for (int k = 1; k <= s[i]; k++)// 枚举选了哪个物品
if (j >= v[i][k])
f[j] = Math.max(f[j], f[j - v[i][k]] + w[i][k]);
System.out.println(f[m]);
}
}
🍑 朴素版
import java.util.*;
class Main{
static int N = 110;
static int[][] f = new int[N][N];
static int[] s = new int[N];
static int[][] w = new int[N][N];
static int[][] v =new int[N][N];
public static void main(String[] args){
Scanner sc = new Scanner(System.in);
int n = sc.nextInt();
int m = sc.nextInt();
for(int i = 1; i <= n; i++ ){
s[i] = sc.nextInt();
for(int j = 1; j <= s[i]; j++){
v[i][j] = sc.nextInt();
w[i][j] = sc.nextInt();
}
}
for(int i =1 ; i <= n; i++){
for(int j = 1; j <= m; j++){
f[i][j] = f[i-1][j];
for(int k = 1; k <= s[i]; k++){
if(j >= v[i][k])
f[i][j] = Math.max(f[i][j],f[i-1][j-v[i][k]] + w[i][k]);
}
}
}
System.out.println(f[n][m]);
}
}