1. 程式人生 > >hihocoder 1055 刷油漆(樹形dp)

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