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

      

  • 相关阅读:
    定时任务 常用cron表达式
    链接UTF-8编码带BOM尾,访问出现404
    centos安装nginx
    cnetos安装jdk
    javaweb数据分页
    mvn clean install对idea中项目结构的影响
    spring使用servlet过滤器filter,进行登录校验
    docker安装mysql并修改远程登陆权限
    使用token令牌控制接口幂等性
    718.最长重复子数组
  • 原文地址:https://www.cnblogs.com/td15980891505/p/5796786.html
Copyright © 2020-2023  润新知