문제 해결
나무 \ (\ 텍스트 {DP} \ ) 기초 질문.
우리는 설정 \ (DP [I] [0/1 ] \) 표시한다 (내가 \) \ 선택된 노드를 (/ \) \ 가장 큰 행복 지수를 선택하지 마십시오.
상태 전이 식 :
\ (DP [I] [0] = A [I] + \ sum_ {v∈son [U]} DP [V] [1.] \) , \ (a [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 \) 상태 노드.