杭电 1520 Anniversary party(没有上司的约会) 树形DP

题意:先输入n个人,接下来n行输入他们的快乐值,再接下来输入一些数对<a,b>,表示b是a的上司(别看反了)!

           要求直属上司和员工不能同时出席宴会,求宴会最大的快乐值。

思路:第一道树形DP题,本来做的动态规划题也不多。

           如果一个上司来了,那么ta的员工一定不来;如果上司不来,那么员工有两种可能,应该取最佳状态。

AC代码:

#include<algorithm>
#include<iostream> 
using namespace std;
int par[6001]; //记录父节点 
int son[6001]; //便于查找根结点 
int dp[6001][2];//dp[i][1]记录有i时的最佳状态,dp[i][0]记录无i时的最佳状态 
int vis[6001];
int n;

void dfs(int root)
{
	vis[root]=1;
	for(int i=1;i<=n;i++)
	{
		if(!vis[i]&&par[i]==root)
		{
			//循环内dfs必须在首位,不然员工的最佳状态(dp[i])没有更新  
			dfs(i); 
			dp[root][1]+=dp[i][0];//有root时,必然不能取ta的员工
			dp[root][0]+=max(dp[i][0],dp[i][1]);
		}
	}
}
int main()
{
	cin>>n;
	int a,b;
	for(int i=1;i<=n;i++)
	{
		cin>>dp[i][1];
	}
	while(cin>>a>>b&&a)
	{
		son[a]++;
		par[a]=b;
	}
	for(int i=1;i<=n;i++)
	{
		if(son[i]==0)
		{
			a=i;
			break;
		} 
	} 
	dfs(a);
	cout<<max(dp[a][0],dp[a][1])<<endl; 
	return 0;
}

VJ提交没什么毛病,HDU貌似输入有点问题。。。。。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值