bzoj3895 取石子(博弈論,記憶化搜尋)

2022-02-27 06:10:13 字數 1291 閱讀 9614

time limit: 1 sec  memory limit: 512 mb

submit: 361  solved: 177

[submit][status][discuss]

alice和bob兩個好朋含友又開始玩取石子了。遊戲開始時,有n堆石子

排成一排,然後他們輪流操作(alice先手),每次操作時從下面的規則中任選乙個:

·從某堆石子中取走乙個

·合併任意兩堆石子

不能操作的人輸。alice想知道,她是否能有必勝策略。

第一行輸入t,表示資料組數。

對於每組測試資料,第一行讀入n。

接下來n個正整數a1,a2…an,表示每堆石子的數量。

對於每組測試資料,輸出一行。

輸出yes表示alice有必勝策略,輸出no表示alice沒有必勝策略。33

1 1 2

23 4

32 3 5

yesno

no100%的資料滿足t<=100,  n<=50. ai<=1000

本來想純粹博弈論,結果發現最終有的情況數不確定,所以只能搜尋一波

因為無論何時,只要每堆都有石子,合併的結果都一樣

所以我們把每一堆石子都先取成1

然後剩下這麼多堆為1的石子,,每次操作有兩種選擇,要麼合併,要麼取走這一堆

然後就結束了

維護選用記憶化搜尋

#include#include

#include

#define rii register int i

using

namespace

std;

int n,dp[55][50055],t,x,l,r,bj[55][50055

];int dplast(int l,int

r)

if(r==1

)

if(bj[l][r])

if(l&&!dplast(l-1

,r))

if(l&&r&&!dplast(l-1,r+1

))

if(l>=2&&!dplast(l-2,r+2+(r?1:0

)))

if(r&&!dplast(l,r-1

))

return dp[l][r]=0;}

intmain()

else

if(r==-1

)

}if(dplast(l,r)==1

)

else

}}

BZOJ3895 取石子(博弈 記搜)

傳送門 我們可以通過石子的堆數和每一堆的個數計算出剩餘的運算元,顯然運算元為奇先手必勝,為偶先手必敗。若將 1的石子堆單獨考慮,對於若干堆 1的石子,運算元為 n i 1x i 那麼我們可以記f a b 表示有a堆 1的石子,1的石子運算元為b的狀態 1表示先手必勝,0表示先手必敗 然後進行記搜,對...

bzoj 3895 取石子(博弈 記憶化搜尋)

time limit 1 sec memory limit 512 mb submit 267 solved 130 submit status discuss alice和bob兩個好朋含友又開始玩取石子了。遊戲開始時,有n堆石子 排成一排,然後他們輪流操作 alice先手 每次操作時從下面的規則...

BZOJ 3895 取石子 SG函式 搜尋

有n堆石子 從某堆石子中取走乙個 合併任意兩堆石子 不能操作的人輸。100 的資料滿足t 100,n 50.ai 1000 容易發現基礎運算元 d sum a i n 1 沒有個數為1的堆還好說,有的話 好麻煩啊啊啊啊啊怎麼可能找規律 然後看題解,woc記憶化搜尋 f i,j 表示i個個數為1的堆,...