hihocoder 1055 刷油漆(樹形dp)
題意:有棵節點數為n的樹,節點都有對應的分數,要求找到以1為根的包含m個結點的樹所得分數最大。
思路:dp[u][j]表示以節點u為根的大小為 j 的樹可得到的最大分數,答案就是dp[1][m]。
狀態轉移方程為:dp[u][j]=max(dp[v1][k1]+dp[v2][k2]+...+dp[vx][kx]),v是u的子節點。
這裡就有了泛化物品的概念(不懂的可以去看一下大牛的揹包九講)。就是說節點u給它的子節點v不同的k值,u從v那裡得到的分數是不一樣的,但是對於每個v至多給一次。然後解決泛化物品的方法就是合二為一(把兩個泛化物品變為一個),不斷縮小規模,最後找到答案。
注意我們要dp[u][j](2<=j<=m)全都用一遍泛化物品,這裡特別要注意是 j 是從小到大,還是從大到小。
對於某個j來說:dp[u][j] = max(dp[u][j], dp[u][j - k] + dp[v][k]),我們要根據這個式子來不斷更新dp[u][j]的值,更新的過程中要用到dp[u][j-k]的值,也就是說比 j 小的值。試想一下如果我們 j 是從小到大更新的,那麼我用dp[v][k]來更新dp[u][j]的時候用到的dp[u][j-k]是有可能包含dp[v][k]的,也就是說我們求dp[u][j-k]的時候可能用過了dp[v][k],但是dp[v][k]在dp[u][j]中至多出現一次,,現在會出現兩次,所以是錯誤的。正解j要從大到小更新。
#pragma warning(disable:4996) #include <cstdio> #include <algorithm> #include <cstring> #include <vector> using namespace std; vector<int>g[105]; int score[105]; int n, m; int dp[105][105];//dp[i][j]表示以i為根的樹中留下j個點可獲得最大分數 bool vis[105]; void add(int u, int v){ g[u].push_back(v); } void dfs(int u){ vis[u] = true; memset(dp[u], 0, sizeof dp[u]); dp[u][1] = score[u]; for (int i = 0; i < g[u].size(); i++){ int v = g[u][i]; if (vis[v])continue; dfs(v); for (int j = m; j >= 2; j--){ for (int k = 1; k < j; k++){ dp[u][j] = max(dp[u][j], dp[u][j - k] + dp[v][k]); } //k的順序無關緊要 /*for (int k = j - 1; k >= 0; k--){ dp[u][j] = max(dp[u][j], dp[u][j - k] + dp[v][k]); }*/ } } } int main(){ //freopen("in.txt", "r", stdin); scanf("%d %d", &n, &m); for (int i = 1; i <= n; i++)scanf("%d", score + i); for (int i = 1; i < n; i++){ int u, v; scanf("%d %d", &u, &v); add(u, v); add(v, u); } memset(vis, false, sizeof vis); dfs(1); printf("%d\n", dp[1][m]); return 0; }
相關推薦
hihocoder 1055 刷油漆(樹形dp)
題意:有棵節點數為n的樹,節點都有對應的分數,要求找到以1為根的包含m個結點的樹所得分數最大。 思路:dp[u][j]表示以節點u為根的大小為 j 的樹可得到的最大分數,答案就是dp[1][m]。 狀
刷油漆(樹形dp)
“是啊,我該怎麼做呢?”小Ho想道,但是如果能很快就自己想出來那也就不是小Ho了,於是小Ho還是老老實實去請教了小Hi。 小Hi聽了小Ho的問題,道:“這個問題不是很簡單麼?來,我們再重複一下之前的步驟——先抽象你的問題。” “好的!應該是這樣的——f(t, m)表示,在以t為根的一棵樹中,選出包含根節點t
HihoCoder 1055 : 刷油漆 樹形DP第一題
tdi 進行 vector coder div 評分 好玩的 scan style 刷油漆 時間限制:10000ms 單點時限:1000ms 內存限制:256MB 描述 上回說到,小Ho有著一棵灰常好玩的樹玩具!這棵樹玩具是由N個小球和N-1根木棍拼湊而
hihocoder 1055 刷油漆(樹形DP+揹包)
dp[i][j]表示i節點,已經染色j個節點的最大價值,那就是樹形DP,每個節點做一次揹包 程式碼: #include <cstdio> #include <cstring> #include <vector> #include <
HihoCoder-1676 樹上的等差數列(樹形DP)
題意 給定一棵 n n n 個節點的樹,每個點都有點權。求一條最長的路徑,是路徑上點的點權序列形成等差數列。 1≤n≤100000 1
#1055 : 刷油漆(樹上的動態規劃)
描述上回說到,小Ho有著一棵灰常好玩的樹玩具!這棵樹玩具是由N個小球和N-1根木棍拼湊而成,這N個小球都被小Ho標上了不同的數字,並且這些數字都是處於1..N的範圍之內,每根木棍都連線著兩個不同的小球,並且保證任意兩個小球間都不存在兩條不同的路徑可以互相到達。沒錯,這次說的還是這棵樹玩具的故事!小Ho的樹玩具
POJ題目1947 Rebuilding Roads(樹形dp)
line div space cpp i++ tex tab wan blue Rebuilding Roads Time Limit: 1000MS Memory Limit: 30000K Total Submissions: 9957 Acc
HDU 4717(樹形DP)
== cnblogs div code 刪除 splay 沒有 str std 由於內存的限制。所以盡量要少開數組。一開始用了數組記錄每個點的度數和每個點的兒子數,還有vis記錄這個點是否處理過。然後超內存了。 實際上兒子數沒有必要存下來,只是每次遍歷自身的時候會用到,然後
Perfect Service UVA - 1218(樹形dp)
pen perf name isp 技術 get sca code esp Perfect Service UVA - 1218 題意:安裝服務器,使得不是服務器的計算機恰好和一臺服務器計算機相連。問最少安多少服務器計算機。 之前一直不理解第三個轉移方程,,今天再看竟然是
lightoj 1382 - The Queue(樹形dp)
volume urn www. vector num clu href get 題目 題目鏈接:http://www.lightoj.com/volume_showproblem.php?problem=1382 題解:簡單的樹形dp加上組合數學。 #incl
bzoj1907: 樹的路徑覆蓋(樹形DP)
ret print ... std getc 覆蓋 amp ostream tchar 一眼題... f[i][0]表示在i連接一個子樹的最小值,f[i][1]表示在i連接兩個子樹的最小值,隨便轉移... 樣例挺強的1A了美滋滋... #inclu
【HDU】1520 Anniversary party(樹形dp)
pre ret set rsa main eof hdu opened event 題目 題目 分析 帶權值的樹上最大獨立集 代碼 1 #include <bits/stdc++.h> 2 using nam
有線電視網(樹形dp)
code 一個 傳輸 mes 收益 滿足 -m 收費 -- 有線電視網 某收費有線電視網計劃轉播一場重要的足球比賽。他們的轉播網和用戶終端構成一棵樹狀結構,這棵樹的根結點位於足球比賽的現場,樹葉為各個用戶終端,其他中轉站為該樹的內部節點。從轉播站到轉播站以及從轉播站到所有
UVa 1220 - Party at Hali-Bula(樹形DP)
style sin col 轉移 time ali main 分析 hal 鏈接: https://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem
[Bzoj3677][Apio2014]連珠線(樹形dp)
print -i 定義 但是 bsp https 開始 sta http 3677: [Apio2014]連珠線 Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 434 Solved: 270[Submit]
Perfect service(樹形dp)
sin space cst ice return 服務器 scan con 表示 Perfect service(樹形dp) 有n臺機器形成樹狀結構,要求在其中一些機器上安裝服務器,使得每臺不是服務器的計算機恰好和一臺服務器計算機相鄰。求服務器的最小數量。n<=10
【POJ】1935 Journey(樹形dp)
scan AR urn vector 答案 span ace CA include 題目 傳送門:QWQ 分析 涼涼。 答案是所有要經過的點到根所經過的邊權和減去最大的邊權。 代碼 vector好慢啊 #include <
[HAOI2015]樹上染色(樹形dp)
long long 價值 記錄 接下來 tin ++ 我們 不用 include [HAOI2015]樹上染色 題目描述 有一棵點數為 N 的樹,樹邊有邊權。給你一個在 0~ N 之內的正整數 K ,你要在這棵樹中選擇 K個點,將其染成黑色,並將其他 的N-K個點染成白色
[HAOI2009]毛毛蟲(樹形dp)
cpp class dfs 代碼 ans 文本文 col 輸入 math [HAOI2009]毛毛蟲 題目描述 對於一棵樹,我們可以將某條鏈和與該鏈相連的邊抽出來,看上去就象成一個毛毛蟲,點數越多,毛毛蟲就越大。例如下圖左邊的樹(圖 1 )抽出一部分就變成了右邊的一個毛毛蟲
題解報告:hdu 2196 Computer(樹形dp)
put cte height ont rst sed mem tle 技術 Problem Description A school bought the first computer some time ago(so this computer‘s id is 1). D