th04 秋靜葉 秋穣子 博弈論

2021-07-31 17:55:04 字數 2564 閱讀 9063

在幻想鄉,秋姐妹是掌管秋天的神明,作為紅葉之神的姐姐靜葉和作為豐收之神的妹妹穰子。如果把紅葉和果實聯絡在一起,自然會想到烤紅薯。烤紅薯需要很多的葉子,才能把紅薯烤得很香,所以秋姐妹決定比比誰能夠收集到最多的紅葉。靜葉將紅葉分成了n堆(編號1..n),並且規定了它們的選取順序,剛好形成一顆有向樹。在遊戲過程中,兩人從根節點開始,輪流取走紅葉,當乙個人取走節點i的紅葉後,另乙個人只能從節點i的兒子節點中選取乙個。當取到某個葉子時遊戲結束,然後兩人會比較自己得到的紅葉數量。已知兩人採用的策略不一樣,靜葉考慮在讓穰子取得盡可能少的前提下,自己取的最多;而穰子想得是在自己盡可能取得多的前提下,讓靜葉取得最少。在兩人都採取最優策略的情況下,請你計算出遊戲結束時兩人的紅葉數量。

遊戲總是靜葉先取,保證只存在一組解。

第1行:1個正整數n,表示紅葉堆數

第2行:n個整數,第i個數表示第i堆紅葉的數量num[i]

第3..n+1行:2個正整數u,v,表示節點u為節點v的父親

第1行:2個整數,分別表示靜葉取到的葉子數和穰子取到的葉子數

6 4 16 16 5 3 1

1 2

2 4

1 3

3 5

3 67 16

對於30%的資料:1 ≤ n ≤ 100,1 ≤ num[i] ≤ 100

對於60%的資料:1 ≤ n ≤ 10,000,1 ≤ num[i] ≤ 10,000

對於100%的資料:1 ≤ n ≤ 100,000,1 ≤ num[i] ≤ 10,000

樣例解釋:

首先靜葉一定能取得節點1的4片紅葉,留給穰子的是節點2和3,均為16片紅葉。

若選取節點2則靜葉下一次可以最多得到5片紅葉,而選擇3靜葉最多也只能得到3片紅葉,

所以此時穰子會選擇節點3,故靜葉最後得到的紅葉數為7,穰子為16。

注意:

保證兩人得到的紅葉數在[0, 2^31-1]。

秋姐妹~~~

不人氣姐妹竟然會有題目……

難道人氣上公升了???

雖然原標題的」穰」字打錯了……

算了咱跟著打錯吧……果然還是不人氣啊……

咳咳,回歸正題。

這是一道博弈論的題。

然而,我認為分類到」樹形dp」上也沒有絲毫問題~

思路:

dp啦~

開乙個dp陣列f[n][2]:

設當前節點為u,

f[u][0]表示以u為根子樹先手最優值,f[u][1]表示後手最優值~

因為這對腹黑姐妹的緣故,應該是這樣:

由於全域性上是靜葉先取,所以:

對於dep為奇數的情況:

f[u][0]=num[u]+f[v][1];

f[u][1]=f[v][0];

這裡的v是u的兒子中下標0的值最大時下標1的結果最小的乙個兒子~

對應某天真妹妹會優先保證自己取到的紅葉最多再坑姐姐~

同理對於dep為偶數的情況:

f[u][0]=num[u]+f[v][1];

f[u][1]=f[v][0];

這裡的v是u的兒子中下標1的值最小時下標0的結果最大的乙個兒子~

對應某腹黑姐姐會優先選擇調戲妹妹再保證自己的紅葉數量~

這樣dp一波就好了……吧?

然而棧溢位…..

於是手寫棧!

具體方式是設定乙個回溯標記記錄這次對這個元素的訪問是不是一次回溯,分開回溯部分和前半部分即可~

#include

#include

#include

#include

#include

using

namespace

std;

const

int inf=0x7fffffff;

inline

int read()

return x;

}const

int n=100233;

int n,num[n],f[n][2];

int to[n<<1],nxt[n<<1],beg[n],tot;

void add(int u,int v)

int dep[n],stk[n],top;

bool first_part[n],as[n],af[n];

void dfs(int root)

if(!first_part[u])

first_part[u]=1;

continue;

}//second part

int mn=inf,mx=-1,tar=0;

if(dep[u])

else

f[u][0]=f[tar][1]+num[u];

f[u][1]=f[tar][0];

top--;

}}int main()

int root=0;

for(int i=1;i<=n;i++)

if(!as[i])

dfs(root);

printf("%d %d\n",f[root][0],f[root][1]);

return

0;}

codevs P1421 秋靜葉 秋穣子

在幻想鄉,秋姐妹決定比比誰能夠收集到最多的紅葉。靜葉將紅葉分成了n堆 編號1.n 並且規定了它們的選取順序,剛好形成一顆有向樹。在遊戲過程中,兩人從根節點開始,輪流取走紅葉,當乙個人取走節點i的紅葉後,另乙個人只能從節點i的兒子節點中選取乙個。當取到某個葉子時遊戲結束,然後兩人會比較自己得到的紅葉數...