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; }