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

题意:中文题,简单明了。

解题思路:首先将所有的可以直接攻克的城堡并在节点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;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值