🍑 题目链接
输入
1000 5
800 2 0
400 5 1
300 5 1
400 3 0
500 2 0
输出
2200
🍑 转换为 分组背包问题
import java.util.ArrayList;
import java.util.Scanner;
public class Main
{
static int n, m, N = 32010, M = 70, V = 10010;
static Pair[] master = new Pair[M];// 主件
static ArrayList<Pair>[] son = new ArrayList[M];
static ArrayList<Pair>[] group = new ArrayList[M];
static int[] f = new int[N];
static class Pair
{
int v;// 价值
int w;// 重要度
public Pair(int v, int w)
{
super();
this.v = v;
this.w = w;
}
}
public static void main(String[] args)
{
Scanner sc = new Scanner(System.in);
n = sc.nextInt();
m = sc.nextInt();
// 初始化
for (int i = 0; i < M; i++)
{
son[i] = new ArrayList<Pair>();
group[i] = new ArrayList<Pair>();
master[i] = new Pair(0, 0);
}
for (int i = 1; i <= m; i++)
{
int v = sc.nextInt();
int w = sc.nextInt();
int q = sc.nextInt();
if (q == 0)// 主件
{
master[i] = new Pair(v, w * v);
} else
{
son[q].add(new Pair(v, w * v));
}
}
int cnt = 1;// 分组背包数
for (int i = 1; i <= m; i++)//枚举所有的物品
{
if (master[i].v != 0)//表示是主件
{
int size = son[i].size();
for (int k = 0; k < 1 << size; k++)
{
int v = master[i].v;
int w = master[i].w;
for (int u = 0; u < size; u++)
{
if ((k >> u & 1) != 0)
{
v += son[i].get(u).v;
w += son[i].get(u).w;
}
}
group[cnt].add(new Pair(v, w));
}
cnt++;
}
}
cnt--;
for (int i = 1; i <= cnt; i++)
for (int j = n; j >= 0; j--)
for (int k = 0; k < group[i].size(); k++)
if (j >= group[i].get(k).v)
f[j] = Math.max(f[j], f[j - group[i].get(k).v] + group[i].get(k).w);
System.out.println(f[n]);
}
}
👨🏫 参考题解