羅区の問題解決[P1352]なしパーティボス

フェイス質問

問題の解決策

ツリー\(\ {テキストDP} \ ) 入門質問。

私たちは、セット(DP [I] [0/1 \ ] \) 意味(\ I)\選択したノード(\ /)\最大幸福指数を選択しないでください。

状態遷移式:
\(DP [I] [0] = A [I] + \ sum_ {v∈son[U]} DP [V] [1] \)\([I] \)それぞれについて幸福指数の従業員。
\(DP [I] [1 ] = \ sum_ {v∈son[U]} \最大{(DP [V] [1]、DP [V] [0])} \)

答えは(\最大{(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\n", max(dp[rt][0], dp[rt][1]));//答案就是根节点选/不选取max
    return 0;
}

概要

したがって、我々は、ツリーを結論付けることができる(\ \テキスト{DP} \ ) 実質的状態の形で:

\(DP [I] [... ] \) を表し\(I \)状態ノード。

おすすめ

転載: www.cnblogs.com/xsl19/p/11826762.html