HDU1520 Anniversary party 树形动态规划

HDU1520 Anniversary party 树形动态规划 

题意:

在一棵有根树上每个节点有一个权值,相邻的父亲和孩子只能选择一个,
求总权值之和最大

思路:

dp[i][0]表示第i个人参加,dp[i][1]表示第i个人不参加 

状态转移方程: 

dp[root][0]+=max(dp[son][1],dp[son][0]);
当前这个点不选,他的孩子可选、可不选,取最大值 
dp[root][1]+=dp[son][0];

当前这个点选择,它的孩子就不能选择 

#include<bits/stdc++.h>
using namespace std;
const int maxn=6005;
int father[maxn];//标记根节点 
int n,a[maxn];
vector<int>G[maxn];
int dp[maxn][2];
void dfs(int root)
{
	dp[root][1]=a[root];
	for(int i=0;i<G[root].size();i++){
		int son=G[root][i];
		dfs(son);
		dp[root][0]+=max(dp[son][1],dp[son][0]);
		dp[root][1]+=dp[son][0];
	}
}
int main()
{
	ios::sync_with_stdio(0);
	int n;
	while(cin>>n){
		//memset(father,-1,sizeof(father));
		for(int i=1;i<=n;i++){
		cin>>a[i];
		G[i].clear();
		dp[i][0]=dp[i][1]=0;
		father[i]=-1;
		}
		
		int l,k;
		while(cin>>l>>k,l+k){
			father[l]=k;
			G[k].push_back(l);
		}
		int root=1;
		while(father[root]!=-1)
		root=father[root];
		dfs(root);
		cout<<max(dp[root][1],dp[root][0])<<endl;
	}	 
	return 0;
}

猜你喜欢

转载自blog.csdn.net/qq_40507857/article/details/80164384
今日推荐