You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

75 lines
3.1 KiB

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

#include <bits/stdc++.h>
using namespace std;
const int N = 110, M = N << 1;
int v[N], w[N];
int n, m, root;
// f[u][i][j] 以u为根在前i个子树中(组)选择最大体积不超过j的所有方案
// 属性max价值
int f[N][N][N];
// 链式前向星
int e[M], h[N], idx, ne[M];
void add(int a, int b) {
e[idx] = b, ne[idx] = h[a], h[a] = idx++;
}
// u:以u为根的树
// 返回值以u为根的树一级子树son的个数
int dfs(int u) {
/*
① 以u为根的树,如果现在剩余体积j>=v[u], 最起码可以把u装下能获取到w[u]的价值
如果你想研究一下以u为根的子树最多可以获得多大价值那u节点是必须装下来否则后续子树根本没机会讨论
*/
for (int j = v[u]; j <= m; j++) f[u][0][j] = w[u];
// ② 考虑u的每个子树
int s = 0;
for (int i = h[u]; ~i; i = ne[i]) { // 枚举u的每个子节点
s++; // 前s个子树
int son = e[i]; // 在链式前向星中,这是几号节点
int c = dfs(
son); // 对子节点son,把它的f[son][c][k]信息填充完整,返回son子树的一级结点个数
/*
目标:填充f[u][i][j],
i:
1~dfs(u)的每个值dfs(u)返回的是u的下级节点个数也就是一级子树个数0上面讨论过了,不用再讨论
j: 枚举每一个u子树的合法空间j
k给定j这么大的空间那么为son这棵子树留多大空间,k∈
[0,j-v[u]],son子树可以贡献的最大价值依定义就是f[son][c][k] f[u][s -
1][j -
k]:在处理s个子树前前s-1个都已经填充完毕可以依赖。由于son占了k个空间那么前序依赖就是f[u][s-1][j-k]
*/
for (int j = v[u]; j <= m; j++)
for (int k = 0; k <= j - v[u]; k++)
f[u][s][j] = max(f[u][s][j], f[u][s - 1][j - k] + f[son][c][k]);
}
return s; // 返回u有多少个子结点
}
int main() {
// 初始化链式前向星
memset(h, -1, sizeof h);
cin >> n >> m; // 物品个数和背包容量
for (int i = 1; i <= n; i++) { // n个物品
int p;
cin >> v[i] >> w[i] >> p; // 体积、价值、父亲
if (p == -1)
root = i; // 对一棵树而言,根是最重要的
else
add(p, i); // 从父亲向儿子建边,一般树都是从上到下建边
}
int s = dfs(root); // 从根节点开始遍历填充DP Table,返回值是root有几个子树
/*
Q:为什么需要dfs返回root有多少个子树呢
A:DP问题一般的答案都在状态转移方程上。比如f[u][i][j]表示以u为根的树中在前i个儿子中去找在体积不超过j的情况下,最大的价值是多少。
我们可以看出最终的答案就是f[root][root的儿子总数][m]
这样看来计算返回出root的儿子总数就是合情合理了
*/
printf("%d\n", f[root][s][m]);
return 0;
}