HDU 1561

题目是一个基础的树型动规的题目,也是我正式做的第一个树型动规的题目吧!!

在看大牛博客的时候,把树型动规看成背包问题加了一个标记数组,但是现在还是不能理解。在构建树的时候,理解了好久。

AC代码:

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;

int dp[208][208],head[208],son[208],q[208];  //数组head里面表示的是该节点的子节点的位置。数组son里面是递归下去的节点位置。
int n,m;
int dfs(int x){
	int i,j,ant;
	int total=1;
	dp[x][1]=q[x];
	for(int z=son[x];z != -1;z = head[z]){
		total+=dfs(z); //减枝,求此时最大值total的组合就可以了。。
		for(i=total;i>=1;i--){
			for(j=1;j+i<=total+1;j++){
				dp[x][i+j]=max(dp[x][i+j],dp[x][i]+dp[z][j]);
			}
		}
	}
	return total;
}
int main(){
	int i,j,sum,a;
	while(scanf("%d%d",&n,&m) && m && n ){
		memset(son,-1,sizeof(son));
		q[0]=0;
		for(i=1;i<=n;i++){  //构建树
			scanf("%d%d",&a,&q[i]);
			head[i]=son[a];
			son[a]=i;
		}
		memset(dp,0,sizeof(dp));
		dfs(0);
		printf("%d\n",dp[0][m+1]);
	}
	return 0;
}
路途中。。。。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值