演算法訓練 結點選擇 (樹形dp)(點權)

2021-07-28 02:20:25 字數 1099 閱讀 8109

問題描述

有一棵 n 個節點的樹,樹上每個節點都有乙個正整數權值。如果乙個點被選擇了,那麼在樹上和它相鄰的點都不能被選擇。求選出的點的權值和最大是多少?

輸入格式

第一行包含乙個整數 n 。

接下來的一行包含 n 個正整數,第 i 個正整數代表點 i 的權值。

接下來一共 n-1 行,每行描述樹上的一條邊。

輸出格式

輸出乙個整數,代表選出的點的權值和的最大值。

樣例輸入 5

1 2 3 4 5

1 21 3

2 42 5

樣例輸出 12

樣例說明

選擇3、4、5號點,權值和為 3+4+5 = 12 。

資料規模與約定

對於20%的資料, n <= 20。

對於50%的資料, n <= 1000。

對於100%的資料, n <= 100000。

權值均為不超過1000的正整數。

題解:樹形dp。(點權)

設dp[i][0]表示不選擇i點時,i點及其子樹能選出的最大權值。

dp[ i ][1]表示選擇i點時,i點及其子樹的最大權值。

所以,狀態轉移方程為:

對於葉子節點 i :

dp[ i ][0] = 0, dp[ i ][1] = k.(點權)

對於非葉子節點 i :

dp[ i ][1] = i點權值 + ∑dp[ j ][ 0 ] (j是i的兒子) 

dp[ i ][0] = ∑max(dp[ j ][ 0 ], dp[ j ][1]) (j是i的兒子)

最後答案的最大權值即為max(dp[1][0], dp[1][1])。

**:

#includeusing namespace std;

vectorg[100010];

int dp[100010][2];

void dfs(int cur,int fa)

}int main()

for(int i=1;i>u>>v;

g[u].push_back(v);

g[v].push_back(u);

} dfs(1,0);

cout<

演算法訓練 結點選擇 樹形DP

問題描述 有一棵 n 個節點的樹,樹上每個節點都有乙個正整數權值。如果乙個點被選擇了,那麼在樹上和它相鄰的點都不能被選擇。求選出的點的權值和最大是多少?輸入格式 第一行包含乙個整數 n 接下來的一行包含 n 個正整數,第 i 個正整數代表點 i 的權值。接下來一共 n 1 行,每行描述樹上的一條邊。...

樹形DP 結點選擇

問題描述 有一棵 n 個節點的樹,樹上每個節點都有乙個正整數權值。如果乙個點被選擇了,那麼在樹上和它相鄰的點都不能被選擇。求選出的點的權值和最大是多少?輸入格式 第一行包含乙個整數 n 接下來的一行包含 n 個正整數,第 i 個正整數代表點 i 的權值。接下來一共 n 1 行,每行描述樹上的一條邊。...

演算法訓練 結點選擇 樹形動態規劃

問題描述 有一棵 n 個節點的樹,樹上每個節點都有乙個正整數權值。如果乙個點被選擇了,那麼在樹上和它相鄰的點都不能被選擇。求選出的點的權值和最大是多少?輸入格式 第一行包含乙個整數 n 接下來的一行包含 n 個正整數,第 i 個正整數代表點 i 的權值。接下來一共 n 1 行,每行描述樹上的一條邊。...