注意在dp中x!=0那一段 其实是对状态的修正
#include <algorithm>
#include <iostream>
#include <cstdio>
using namespace std;
const int MAXN = 300 + 10;
int n,m,tot,head[MAXN],k[MAXN],son[MAXN],f[MAXN][MAXN];
struct Edge{
int u,v,to;
Edge(){}
Edge(int u, int v, int to) : u(u), v(v), to(to) {};
}e[MAXN];
inline void add(int u, int v) {
e[++tot] = Edge(u,v,head[u]);
head[u] = tot;
}
void dfs(int x) {
if(!head[x]) son[x] = 1;
for(int i=head[x]; i; i=e[i].to) {
dfs(e[i].v);
son[x] += son[e[i].v];
}
}
void dp(int x) {
for(int i=head[x]; i; i=e[i].to) {
int v = e[i].v;
dp(v);
for(int t=m; t>=0; t--)
for(int j=t; j>=0; j--)
f[x][t] = max(f[x][t], f[v][j] + f[x][t-j]);
}
if(x != 0)
for(int t=m; t>0; t--)
f[x][t] = f[x][t-1] + k[x];
}
int main() {
scanf("%d %d", &n, &m);
for(int i=1; i<=n; i++) {
int u;
scanf("%d %d", &u, &k[i]);
if(u != 0)
add(u, i);
else
add(0, i);// ³¬¼¶Ô´µã0
}
dfs(0);
dp(0);
printf("%d\n", f[0][m]);
return 0;
}

本文深入探讨了DP算法的应用场景及实现细节,通过一个具体的树形DP实例来讲解如何进行状态转移与修正,以达到最优解。代码示例清晰地展示了递归与DP相结合的方法。
731

被折叠的 条评论
为什么被折叠?



