這題和之前那個hdu2616有著奇妙的異曲同工之處。。都是要求某個點能夠到達的最大權重的地方。。。
但是,這題加了個限制,要求最多隻能夠踩到c個陷阱,一單無路可走或者命用光了,就地開始清算總共得分之和。
於是首先考慮,c的大小只有4,那麼可以進行非常方便的狀態轉移,即將之前2616中的各個矩陣都加一維,設定為走到這一步的時候,可以踩得陷阱的個數——如果可以踩得陷阱的個數是0就意味著不能夠行走,於是直接規定,所有是0條命的都自動為0。
之後按照上題的方式進行列舉,有所不同的是,需要考慮下陣列傳遞引數的方式,我的做法是將臨時變數開到全域性空間,這樣就就可以保證不會爆棧什麼的了。
考慮每個點,如果該電有陷阱,那麼所有的轉移,都必須按是少了一條命的結果,否則就是直接轉移,同事我們認為,由於沒有點數小於等於0的點,所以,必然可以得出,在同乙個點上,當兩個人的命數量不相等時,必然會有命多的「最大得分不小於命少的最大得分」。於是只需要普通的更新就是了。
#include#include#include
#include
using
namespace
std;
const
long
long maxn = 50233
;vector
g[maxn];
const
long
long limit = 4
;long
long
child[maxn][limit];
long
long
child_left[maxn][limit];
long
long
child_right[maxn][limit];
long
long
tmp[maxn][limit];
bool
trap[maxn];
long
long
arr[maxn];
long
long
n, c;
long
long max(long
long a, long
long
b)void get_child(int now, int
last)
for (int i = 1; iarr[now];
}void get_left(int now, int
last)
else
for (int i = 1; iarr[now];
long
long ttmp[limit]; memset(ttmp, 0, sizeof
(ttmp));
for (int i = 0; ii)
}void get_right(int now, int
last)
else
for (int i = 1; iarr[now];
long
long ttmp[limit]; memset(ttmp, 0, sizeof
(ttmp));
for (int i = len - 1; i >= 0; --i)
}void
init()
get_child(
0, -1
); get_left(
0, -1
); get_right(
0, -1
);
long
long ans = 0
;
for (int i = 0; ii)
cout
<< ans <}int
main()
HDU 4616 Game 樹形dp,兩遍dfs
hdu 4616 game 題意 給乙個n 個節點和n 1條邊的樹。每個節點代表乙個房間,每個房間都放有乙個價值為正的禮物,有的房間有陷阱,有的房間沒陷阱,最多可以經過 c 個陷阱 第 c個陷阱時就應該停止 可以從任意的房間開始行走,每個房間只能走一次,求獲得的禮物的最大價值和?資料範圍 n 5 1...
HDU 1520 簡單樹形dp
題意 乙個大學要舉行職工party。為使party中每個人都玩的開心,直接上司和下屬關係的員工不能同時參加。每個人都有各自的歡樂值。問如何邀請使得總歡樂值最大。dp i 1 表示選擇i點 dp i 0 表示不選擇i點 include include include include using nam...
HDU 2196 樹形dp入門
鏈結 傳送門 題意 給你乙個n個節點的棵樹,然後給你和 第i臺電腦與第a臺電腦相連的花費 v 問你最長的線路是多長 求樹上任意節點所能達到的最遠點的距離 樹形dp 開個陣列 分別記錄這個點到子樹最遠節點的最長距離和次長距離和記錄到父節點上的最長距離這樣在樹上dp 1.求子樹最長和次長 dp u 0 ...