動態規劃 樹形DP 題解 戰略遊戲

2021-09-11 18:30:59 字數 2255 閱讀 4557

題意思路

**woj#2532 戰略遊戲

洛谷p2016 戰略遊戲

這道題主要是看邊的情況。

第一行 n,表示樹中結點的數目。

第二行至第n+1行,每行描述每個結點資訊,依次為:該結點標號i,k(後面有k條邊與結點i相連)。

接下來k個數,分別是每條邊的另乙個結點標號r1,r2,…,rk。

對於乙個n(0輸出檔案僅包含乙個數,為所求的最少的士兵數目。

在一棵樹上取若干個點,使得所有邊都被鏈結。求點的個數的最小值。

對於這類最值問題,應當用動態規劃求解。

設s

ss是樹的根,則設f[s

]f[s]

f[s]

表示求以s

ss為根的子樹上需要安放的最少士兵數量。我們希望用s

ss的兒子的對應資訊來推出f[s

]f[s]

f[s]:s

ss有放和不放兩種可能。當s

ss節點放時,它的子節點放和不放都可以;當s

ss節點不放時,它的子節點必須放。所以需要加維來表示樹的根結點是否選取,才能從子樹推算出父親的最大值。

設f [i

,1

]f[i,1]

f[i,1]

表示i

ii點放士兵時,以i

ii為根的子樹需要的最少士兵數目;f[i

,0

]f[i,0]

f[i,0]

表示i

ii點不放士兵時,以i

ii為根的子樹需要的最少士兵數目。

當點i

ii不放時,則它的所有兒子都必須放;

f [i

][0]

=∑f[

j][1

]f[i][0]=∑f[j][1]

f[i][0

]=∑f

[j][

1];其中j

jj為i

ii的兒子。

當點i

ii放時,則它的所有兒子放與不放無所謂,但應該取兩種情況的最小值;

f [i

,1]=

∑min

(f[j

][1]

,f[j

][0]

)f[i,1]=∑min(f[j][1],f[j][0])

f[i,1]

=∑mi

n(f[

j][1

],f[

j][0

]);其中j

jj為i

ii的兒子

初始條件:

f [i

][0]

=0,f

[i,1

]=

1f[i][0]=0,f[i,1]=1

f[i][0

]=0,

f[i,

1]=1;an

s=mi

nf[s

][0]

,f[s

][1]

ans=min

ans=mi

nf[s

][0]

,f[s

][1]

#include

#include

#include

using

namespace std;

const

int maxn=

1510

;int n,s,cnt=

2,ans=0;

int first[maxn]

,f[maxn][2

];struct edge

;edge e[maxn<<1]

;inline

intread()

while

(isdigit

(c))

return f?

-x:x;

}inline

void

add(

int u,

int v)

inline

void

dfs(

int x,

int fa)

}int

main()

} s=1;

dfs(0,

-1);

ans=

min(f[0]

[0],f[0]

[1])

; cout

}

樹形DP 戰略遊戲

鮑勃喜歡玩電腦遊戲,特別是戰略遊戲,但有時他找不到解決問題的方法,這讓他很傷心。現在他有以下問題。他必須保護一座中世紀城市,這條城市的道路構成了一棵樹。每個節點上的士兵可以觀察到所有和這個點相連的邊。他必須在節點上放置最少數量的士兵,以便他們可以觀察到所有的邊。你能幫助他嗎?例如,下面的樹 只需要放...

樹形DP 戰略遊戲

description input 輸入檔案中資料表示一棵樹,描述如下 第一行 n,表示樹中結點的數目。第二行至第n 1行,每行描述每個結點資訊,依次為 該結點標號i,k 後面有k條邊與結點i相連 接下來k個數,分別是每條邊的另乙個結點標號r1,r2,rk。對於乙個n 0 n 1500 個結點的樹,...

戰略遊戲 樹形DP入門)

題目鏈結 here 題目分析 放置哨兵無非兩種情況,放或不放,我們可以用dp i 1 來表示第i個結點放置哨兵,dp i 0 來表示第i個結點不放置哨兵,我們可以從上往下,從左往右來遍歷樹,所以這就用到了樹形dp的知識,我們很容易知道,如果父親結點沒放哨兵,那麼子結點肯定要放置哨兵,如果父親放置了哨...