HDU 1561 The more, The Better(树形DP)

53 篇文章 0 订阅
37 篇文章 1 订阅

dp[i][j]表示为在i结点上选择j个节点的最大值

转移方程:dp[u][j+k]=max(dp[u][j+k],dp[u][j]+dp[v][k]);//在i的结点上选择j+k的的值为 max(在i结点上选择j+k个结点的值,在i结点上选j个结点+在i的儿子结点v上选择k个结点的值)

#include <iostream>
#include <cstdio>
#include <memory.h>
using namespace std;
const int maxn=203;
struct edge
{
	int v,next;
}es[maxn];
int head[maxn],w[maxn],dp[maxn][maxn],n,m;
int dfs(int u){
	dp[u][1]=w[u];
	int tot=1;
	for (int ne=head[u];ne!=-1;ne=es[ne].next){
		int v=es[ne].v;
		tot+=dfs(v);
		for (int j=tot+1;j>=1;--j){//因为加了个超级原点,所以总数+1
			for (int k=1;j+k<=tot;++k){
				dp[u][j+k]=max(dp[u][j+k],dp[u][j]+dp[v][k]);//在i的结点上选择j+k的的值为 max(在i结点上选择j+k个结点的值,在i结点上选j个儿子结点+在i的儿子结点v上选择k个儿子结点的值)
			}
		}
	}
	return tot;
}
int main(){
	while (scanf("%d%d",&n,&m)){
		if(!n&&!m)break;
		memset(head,-1,sizeof(head));
		memset(dp,0,sizeof(dp));
		int eidx=0;
		for (int i=1;i<=n;++i){
			int v;
			scanf("%d%d",&v,&w[i]);
			es[eidx].v=i;
			es[eidx].next=head[v];
			head[v]=eidx++;
		}
		dfs(0);
		printf("%d\n",dp[0][m+1]);
	}
	return 0;
}


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值