zoukankan      html  css  js  c++  java
  • 题解【洛谷P1352】没有上司的舞会

    题面

    题解

    树形( ext{DP})入门题。

    我们设(dp[i][0/1])表示第(i)个节点选(/)不选的最大快乐指数。

    状态转移方程:
    (dp[i][0]=a[i]+sum_{v∈son[u]}dp[v][1]),其中(a[i])为每个员工的快乐指数。
    (dp[i][1]=sum_{v∈son[u]}max{(dp[v][1],dp[v][0])})

    答案为(max{(dp[rt][0],dp[rt][1])}),其中(rt)为没有上司的员工。

    转移一下即可。

    代码

    #include <bits/stdc++.h>
    #define itn int
    #define gI gi
    
    using namespace std;
    
    inline int gi()
    {
    	int f = 1, x = 0; char c = getchar();
    	while (c < '0' || c > '9') {if (c == '-') f = -1; c = getchar();}
    	while (c >= '0' && c <= '9') x = x * 10 + (c ^ 48), c = getchar();
    	return f * x;
    }
    
    const int maxn = 6003;
    
    int n, a[maxn], tot, head[maxn], ver[maxn * 2], nxt[maxn], ans, vis[maxn], rt;
    int dp[maxn][2];//0:xuan 1:buxuan
    
    inline void add(int u, int v)
    {
    	ver[++tot] = v, nxt[tot] = head[u], head[u] = tot;
    }
    
    void dfs(int u, int f)
    {
    	dp[u][0] = a[u];
    	for (int i = head[u]; i; i = nxt[i])
    	{
    		int v = ver[i];
    		if (v == f) continue;
    		dfs(v, u);
    		dp[u][0] += dp[v][1];
    		dp[u][1] += max(dp[v][0], dp[v][1]);//状态转移
    	}
    }
    
    int main()
    {
    	n = gi();
    	for (int i = 1; i <= n; i+=1) a[i] = gi();
    	for (int i = 1; i < n; i+=1)
    	{
    		int u = gi(), v = gi();
    		add(u, v);
    		add(v, u);
    		vis[u] = 1;
    	}
    	int h = gi(), o = gi();
    	for (int i = 1; i <= n; i+=1) if (!vis[i]) {rt = i; break;}//找到根节点,即没有上司的员工编号
    	dfs(rt, 0);
    	printf("%d
    ", max(dp[rt][0], dp[rt][1]));//答案就是根节点选/不选取max
    	return 0;
    }
    

    总结

    由此,我们可以得出树形( ext{DP})的状态的基本形式:

    (dp[i][…])表示第(i)个节点的状态。

  • 相关阅读:
    解题报告 The Rabbits
    解题报告 Function
    解题报告 大富翁
    解题报告 QUE
    解题报告 The cubes(即 银河英雄传说 NOI 2002)
    解题报告 xth 的苹果树
    解题报告 solve
    解题报告 Paid Roads
    解题报告 最小波动
    解题报告 Pizza
  • 原文地址:https://www.cnblogs.com/xsl19/p/11826762.html
Copyright © 2011-2022 走看看