51nod 1531 樹上的博弈

2021-07-25 08:29:55 字數 1198 閱讀 1749

有一棵n個點的有根樹,他有m個葉子結點(葉子結點是那些沒有孩子的結點)。邊由父親指向孩子。數字1到m被分配到每乙個葉子中。每乙個葉子有乙個數字,並且每乙個數字恰好被分配到乙個葉子中。

剛開始的時候根部有乙個棋子。兩個玩家輪流移動棋子,每一步都會將這個棋子向他的某乙個孩子移動;如果玩家不能再移動棋子了,那麼遊戲結束。遊戲的結果就是棋子所在葉子上面的數字。遊戲的先手想要這個數字最大化,而後手想要這個數字最小化。

山巴布裡想要給這些葉子分配數字使得最終結果最大,而馬族塔想要給這些葉子分配數字使得最終結果最小。那麼當山巴布裡來分配數字的時候遊戲結果會是多少?馬族塔分配的時候又是多少呢?山馬布里和馬族塔並不參加遊戲,而是另外兩個非常聰明的人來參加遊戲。

樣例解釋:在這個樣例中,樹有三個葉子:3,4和5。如果把數字3分配給3號結點,那麼第乙個選手就能夠讓棋子到達那兒,最終結果就是3。另一方面,很明顯,無論怎麼分配數字,第乙個選手讓棋子達到最小數字是2。

考慮最大化怎麼做。

假設我的答案是ans,設f[i]表示i子樹內需要至少安置多少個》=ans才能使在這個節點往後操作一定能使答案為ans。

顯然i是先手操作就對每顆子樹的f取min,否則求和。

顯然m-f[1]是最大答案。

最小化同理。

hljs perl">#include

#define fo(i,a,b) for(i=a;i<=b;i++)

using namespace std;

const int maxn=200000+10;

int f[maxn],d[maxn],h[maxn],go[maxn],next[maxn];

int i,j,k,l,r,mid,n,m,ans,tot;

void add(int

x,int

y)void dfs(int

x) while (t)

}void dg(int

x) if (d[x]%2==0)

}else

}}void dg2(int

x) if (d[x]%2==1)

}else

}}int main()

dfs(1);

dg(1);

printf("%d ",m-f[1]+1);

dg2(1);

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

}

1531 樹上的博弈

51nod 1531 樹上的博弈 樹型dp 1.建樹,複雜度o n 2.自下向上dp,複雜度o n 記錄狀態量 當前該棵子樹 分配m個數,答案是第k小數 進行狀態轉移 由於有先後手,並且有 分配希望 最大與最小 兩種前提。因此2 2 4種狀態,不過最大最小是對稱關係,因此可以只計算其中2種,另2種根...

51nod 1490 多重遊戲(樹上博弈)

1490 多重遊戲 codeforces 基準時間限制 1 秒 空間限制 131072 kb 分值 40 難度 4級演算法題 有乙個兩人遊戲,遊戲是這樣的,有n個非空串。在遊戲的過程是,兩個玩家輪流向乙個字串後面加字母,剛開始字串是空的。每一次操作是向當前字串後面新增字元,形成的新字串一定要是這n個...

51nod 1068 簡單博弈

思路 手動打表,n 1 a出1 a勝 2 a出2 a勝 3 a只能出2的整數冪 這個數 3,所以只能出1,2 a出1的時候,b就是2的情況,b勝 a出2的時候,b就是1的情況,b勝 4 a只能出2的整數冪 這個數 3,所以只能出1,2,4 直接拿4,a勝 5 a只能出2的整數冪 這個數 3,所以只能...