您的位置:首页 > 其它

hdu 1561 The more, The Better 树形DP入门题

2013-07-18 15:27 260 查看
题意:中文题,简单明了。

解题思路:首先将所有的可以直接攻克的城堡并在节点0的下面,然后对于每个节点,利用分组背包的思想,该节点的各个子树看成各个背包。

#include <stdio.h>
#include <string.h>

struct EDGE {
int to, next;
}edge[222];

int head[222], E, cnt[222], dp[222][222], val[222];
void newedge(int u, int to) {
edge[E].to = to;
edge[E].next = head[u];
head[u] = E++;
}
void init() {
memset(head, -1, sizeof(head));
memset(dp, 0 , sizeof(dp));
E = 0;
}
void dfs(int u) {
cnt[u] = 1;
if(head[u] == -1) {
dp[u][1] = val[u];
return ;
}
int i, j, k;
for(i = head[u];i != -1; i = edge[i].next) {
int to = edge[i].to;
dfs(to);
cnt[u] += cnt[to];
for(j = cnt[u]-1;j >= 0; j-- ) {
for(k = 1;k <= cnt[to]; k++) if(j+k < cnt[u] && dp[u][j]+dp[to][k] > dp[u][j+k])
dp[u][j+k] = dp[u][j] + dp[to][k];
}
}
if(u != 0) {
for(i = cnt[u];i >= 1; i--)
dp[u][i] = dp[u][i-1]+val[u];
dp[u][0] = 0;
}

}

int main() {
int i, j, k, n, m, a;
while(scanf("%d%d", &n, &m) != -1 && n) {
init();
for(i = 1;i <= n; i++) {
scanf("%d%d", &a, &val[i]);
newedge(a, i);
}
val[0] = 0;
dfs(0);
printf("%d\n", dp[0][m]);
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  树形DP 分组背包