題目大意:一共n行20列,每行若干個棋子,對每個棋子,可以移動到右邊距離最近的空格。兩個人輪流移動,不能移動者輸,問先手是否可以勝利
解題思路:每行20格,我們可以把狀態壓縮到乙個int變數state裡,對於每乙個狀態,求出下乙個狀態做上標記,sg[state]就是mex,也就是vis陣列中第乙個為false的下標。然後再把n行的sg函式進行異或,為0則必敗,否則必勝。預處理暴力從0開始列舉,也可以記憶化搜尋。
#include #include #include #include #include #include #include #include #include #include #include #include using namespace std;
typedef long long ll;
#define fin freopen("in.txt", "r", stdin);
#define fout freopen("out.txt", "w", stdout);
#define lson l, mid, cur << 1
#define rson mid + 1, r, cur << 1 | 1
const int inf = 0x3f3f3f3f;
const int maxn = (1 << 20) + 50;
const int mod = 1e9 + 7;
int sg[maxn];
int dp(int state)
}for (int i = 0; i < 22; i++)//找到最小的mex沒有出現過的下標
if (!vis[i])
return sg[state];
}int main()
ans ^= sg[tstate];
}printf("%s\n", ans == 0 ? "no" : "yes");
}return 0;
}
hdu 5724 Chess 組合博弈
題意 給你乙個n行20列的棋盤,棋盤裡面有些棋子,每個棋子每次只能往右走一步,如果右邊有棋子,可以跳過去,前提是最右邊有格仔,如果當前選手走到沒有棋子可以走了,那麼就算輸,問你先手是否會贏 題解 一看就知道是組合博弈的問題,關鍵在於如果求sg值,這裡要把一行看成乙個狀態,然後根據sg值的定義去求,如...
2016多校聯賽 hdu 5724 Chess
此題就是乙個sg函式的題目,需要找出每一行的sg值,然後異或就可以咯。找sg需要在初始化的時候就找,也就是在t之前,暴力找出所有情況的sg。注意這個題只有20行,所以狀態壓縮一下就可以,每一行有棋子的地方就置為1,每一的地方就是0.include include include include in...
ACdream1132 chess 狀態壓縮DP
題意 有乙個n n的棋盤,要在上面放將,乙個將可以控制本身的位置和上下左右四格,棋盤上有一些地方不能放將,但是這些點也要被控制,問最少要放幾個將。思路 狀態壓縮dp,我們反過來想,最多空多少格不放,能控制所有的格仔。對於資料,我們先做乙個預處理,求出每行可以的狀態和這個狀態對應空的格數,這裡我用f ...