admin 發表於 2023-8-23 16:07:51

進阶博弈 : 略微复杂の状压分裂遊戲

起首是本身dp根本很差,然後是状压写的少,好不易碰到赶快記下来。

另有就是近来在學latex了,写了好几個月發明這個問题一向没解决,井底之蛙了属因而。

原题链接:C. More Reclamation

题意:

有一條 2 \, \cdot n 的运河。這條运河是首要的商業通道,是以运河必需连结连通(4连通)。两個國度起頭争取地皮,他們争取地皮的方法是填河造陸,可是填河造陸的限定是不克不及让运河堵上。河中存在一些石頭,有石頭的處所是不克不及填埋的。不克不及填河的國度會以失败了结,請問谁會获胜。

阐發:

每次咱們在填入一块地的時辰,對面的持续三块 , , 都不克不及被填埋,如圖所示:一块完备的圖被朋分成為了两块。

而且每次填入一块城市發生朋分,是以,這道题的本色實在就是割裂遊戲。咱們必要求出每種块的sg函数,最後异或起来便可。

状况紧缩:

咱們描写一個方块必要三個参数:kubet, len,up,down。 len暗示块的长度, up 暗示上真個状况, down 暗示下真個状况。此中上下的状况一共有三種:两块都没被占,左侧没被占,右侧没被占,咱們别離用 0/1/2 暗示,那末终极 sg 便可以暗示状况的sg函数了。

状况割裂:

罗列上下状况和填入的状况,填入的状况對付新發生的两块的上下状况要末是1要末是2,對付不克不及填的部門要判掉。然後暴力异或赛到set里便可。

S.insert(sg\oplus sg[刷卡換現金,down]);

代码:

int r, n, m, q;
int a;
int sg;
int get_sg() {
for(int i = 1; i < N ; i ++ )
for(int up = 0 ; up < 3; up ++ )
for(int down = 0 ; down < 3; down ++ ) {
set<int> S;
for(int j = 0 ; j < i ; j ++ )
for(int k = 1; k <= 2; k ++ ) {
if((j == 0 && k != up && up) || (j == i - 1 && k != down && down)) continue;
S.insert(sg ^ sg);
}
int ans = 0;
while(S.count(ans)) ans ++ ;
sg = ans;
}
}
signed main() {
get_sg();
// cin >> r >> n;
r = read(), n = read();
for(int i = 1; i <= n ; i ++ ) {
int x, y;
x = read(), y = read();
y -- ;
a = 1;
a = 1;
a = 1;
a = 1;
}
int len = 0,去疤藥膏, up = 0, down = 0, res = 0;
for(int i = 1; i <= r ; i ++ ) {
if(a + a == 2) continue;
int j = i;
while(j <= r && a + a < 2) j ++ ;
len = j - i;
up = (a + a == 0) ? 0 : (a ? 2 : 1);
down = (a + a == 0) ? 0 : (a[小琉球精選酒吧,0] ? 2 : 1);
// cout << i << " " << j << " " << len << " " << up << " " << down << endl;
res ^= sg;
i = j;
}
if(res) cout << "WIN";
else cout << "LOSE";
}
頁: [1]
查看完整版本: 進阶博弈 : 略微复杂の状压分裂遊戲