zoukankan      html  css  js  c++  java
  • CF633F The Chocolate Spree

    CF633F The Chocolate Spree

    洛谷传送门

    题意翻译

    给出一棵树,每个节点有一个权值,求出不相交的两条链的最大权值和。


    题解:

    树形DP好题。

    众所周知,作为一道DP题,当你没办法转移的时候,你要想着再多来几个状态帮你转移。

    比如这道题:

    我们直接设答案:(dp[x][0])表示以x为根的子树选出两条不相交链的最大值。

    怎么转移呢?

    首先设当前节点为(x),其中一个儿子为(y)。转移要对以下四步取max:

    首先,要在以(y)为根的子树中选两条不相交链,这可能是答案。然后,在(y)为根的子树中选一条,在其他儿子里选一条。再然后,从该点和子树中分别选出半条链,再从子树里选一条完整链。最后,第三条的反向思路也是可以的。

    然后发现一时半会没办法维护这四种情况。于是再来几个状态:(dp[x][0])表示以(x)为根的子树选出一条链的最大值。(g[x])表示以(x)为根的子树中从(x)到叶子再加上一条不相交链的最大值。(down[x])表示从(x)到叶子节点的最大值。然后为了快速维护第二种情况,再加上(h[x])表示所有儿子的(dp[y][0])最大值。

    大功告成,还有亿点点细节。

    代码:

    #include<bits/stdc++.h>
    #define ll long long
    using namespace std; 
    const int maxn=1e5+5;
    const int INF=0x3f3f3f3f;
    int n;
    vector<int> e[maxn];
    int w[maxn];
    ll dp[maxn][2],g[maxn],h[maxn],down[maxn];
    void dfs(int x, int f) 
    {	
        dp[x][0]=dp[x][1]=g[x]=down[x]=w[x];
        h[x]=0;	
        for(int i=0;i<e[x].size();i++) 
        {	
        	int u=e[x][i];		
        	if(u==f) 
                continue;	
    		dfs(u,x);			
        	dp[x][0] = max(dp[x][0], dp[u][0]);	
        	dp[x][0] = max(dp[x][0], dp[x][1]+dp[u][1]);	
    		dp[x][0] = max(dp[x][0], down[x]+g[u]);		
            dp[x][0] = max(dp[x][0], g[x]+down[u]); 	
    	    dp[x][1] = max(dp[x][1], dp[u][1]);	
    	    dp[x][1] = max(dp[x][1], down[x]+down[u]); 	
    	    g[x] = max(g[x], w[x]+g[u]);	
    	    g[x] = max(g[x], down[x]+dp[u][1]);		
    	    g[x] = max(g[x], down[u]+w[x]+h[x]); 
    	    h[x] = max(h[x], dp[u][1]); 		
    	    down[x] = max(down[x], down[u]+w[x]);	
        }
    }
    int main()
    {    
    	scanf("%d",&n);	
    	for(int i=1;i<=n;i++)		
    	    scanf("%d",&w[i]);	
    	for(int i=1;i<n;i++) 
        {		
        	int u,v;		
        	scanf("%d%d",&u,&v);		
        	e[u].push_back(v);
            e[v].push_back(u);
        }	
    	dfs(1,0);	
    	printf("%lld",dp[1][0]);    
    	return 0;
    }
    
  • 相关阅读:
    事件对象
    事件
    父元素高度为auto,子元素使用top:-50%没有效果的问题
    Window.open 实现导航与打开窗口,导航到一个特定链接地址,也可以打开一个新的浏览器窗体
    8.0 BOM对象
    7.4 私有变量
    006_函数填充_计算列
    004_005_数据区域读取_填充数字
    003_行_列_单元格
    002_读写文件
  • 原文地址:https://www.cnblogs.com/fusiwei/p/14037173.html
Copyright © 2011-2022 走看看