zoukankan      html  css  js  c++  java
  • poj 2324 Anniversary party(树形DP)

    /*poj 2324 Anniversary party(树形DP)
    ---用dp[i][1]表示以i为根的子树节点i要去的最大欢乐值,用dp[i][0]表示以i为根节点的子树i不去时的最大欢乐值,
    ---于是当i去时,i的所有儿子都不能去:dp[i][1]=sum(dp[j][0])+a[i],其中j是i的儿子节点。
    ---当i不去时,i的儿子可去也可不去:dp[i][0]=sum(max(dp[j][0],dp[j][1])),j是i的儿子节点
    ---边界条件:当i时叶子节点时,dp[i][1]=a[i],dp[i][0]=0;
    */
    #define _CRT_SECURE_NO_DEPRECATE
    #include<iostream>
    #include<vector>
    #include<algorithm>
    using namespace std;
    const int maxn = 6000 + 5;
    
    int a[maxn], dp[maxn][2];
    vector<int>vec[maxn];
    
    //记忆化搜索
    int dfs(int u, int k){
    	if (dp[u][k] >= 0)return dp[u][k];
    	int n = vec[u].size();
    	if (k == 0)dp[u][k] = 0;
    	else dp[u][k] = a[u];
    	for (int i = 0; i < n; i++){
    		int v = vec[u][i];
    		if (k == 0) dp[u][0]+=max(dfs(v, 1), dfs(v, 0));
    		else dp[u][1] += dfs(v, 0);
    	}
    	return dp[u][k];
    }
    int main(){
    	int n,i,u,v;
    	while (scanf("%d%d", &n, &a[1])&&n){
    		for (i = 0; i <= n; i++) vec[i].clear();
    		
    		for (i = 2; i <= n; i++)scanf("%d", &a[i]);
    
    		for (i = 1; i < n; i++){
    			scanf("%d%d", &u, &v);
    			vec[v].push_back(u);
    		}
    		memset(dp, -1, sizeof(dp));
    		int ans = -1;
    		for (i = 1; i <= n; i++)
    			ans = max(ans, max(dfs(i, 0), dfs(i, 1)));
    		printf("%d
    ", ans);
    	}
    }
    

      

  • 相关阅读:
    分布式 and 集群
    时间复杂度



    线性表 & 散列表
    栈 & 队列
    数组 & 链表
    数据结构&算法
    Docket 容器引擎
  • 原文地址:https://www.cnblogs.com/td15980891505/p/5796786.html
Copyright © 2011-2022 走看看