題目大意:
有g種不同顏色的小球,b個袋子,每個袋子裡面有若干個每種小球
兩人輪流取袋子,當袋子裡面的同色小球有s個時,會合併成乙個魔法球,並被此次取袋子的人獲得
成功獲得魔法球的人可以再次取
求二者都進行最優策略之後兩人所得魔法球個數差
分析:博弈,資料很小,自然想到了可以搜尋所有狀態
然後從每一步的子狀態中找到對當前人(這一步的先手)最有利的狀態即可
直接搜尋還是會超時的,於是想到用狀態壓縮一下,做記憶化搜尋
然後其實就是乙個狀壓dp了
通過某個狀態對於先手的最優子狀態進行轉移。。
**如下
#include #include#include
#include
#include
#include
using
namespace
std;
#define maxn 10000typedef
struct
node
node;
node dp[
2097152
];bool vi[2097152
];int num[25][25
];int p[8
];int
g,b,s,k,m,x;
void dfs(int state,int
turn)
if(vi[state])
intok;
node t;
node ans;
ans.a=-1000000
; ans.b=0
;
int pp[8
]; memcpy(pp,p,
sizeof
(pp));
for(int i=0;i)
int tur=ok?turn:!turn;//
是否交換選手
dfs(st,tur);
memcpy(p,pp,
sizeof
(pp));
t.a+=ok;
if(tur==turn) //
子狀態的先手所要轉移到的狀態相同
else
//選手交換了
if(t.a-t.b>ans.a-ans.b)
}vi[state]=1
; dp[state]=ans;
return;}
intmain()
}memset(p,
0,sizeof
(p));
memset(vi,
0,sizeof
(vi));
dfs(
0,0);
printf(
"%d\n
",dp[0].a-dp[0
].b);
}return0;
}
HDU 4778 記憶化搜尋 狀壓
給出g種寶石,b個包,和s,s代表到時候每種顏色的寶石湊齊s個能變成乙個魔法石 每個包裡有n種寶石,分別為c1,c2.然後兩人輪流拿包,每個包只能拿一次,拿出包把寶石放地上。如果能變成魔法石則拿走魔法石,下一次還這個人拿包,沒變成則換人。魔法石的個數就是獲得分數,問兩人最優的時候分差是多少。狀壓記憶...
狀壓 博弈dp
傳送門 題目大意 遊戲的雙方能在 1 n 之間選擇乙個數加到sum上,每個數只能選擇一次。誰先將sum 變得 max 誰就贏了。現在問你,給定 n sum.先手是否能贏 兩方採取最優策略 n 20 max 300 思路 很容易發現n 很小,可以直接狀態壓縮。但是有乙個問題。直觀的想法是開二維陣列,這...
狀壓dp 玉公尺田 狀壓dp
相關 強相關 327.玉公尺田 狀壓dp 小國王 狀壓dp 是井字形,本題是十字形。思路 狀態計算 時間複雜度 n 2 n 2n o n 22n 12 2 24n 2 n 2 n o n2 12 2 n 2n 2 n o n22n 12 224 看著妥妥超時,但是裡面合法狀態很少 依舊可以過 在此,...