題目
傳統的nim遊戲是這樣的:有一些火柴堆,每堆都有若干根火柴(不同堆的火柴數量可以不同)。兩個遊戲者輪流操作,每次可以選乙個火柴堆拿走若干根火柴。可以只拿一根,也可以拿走整堆火柴,但不能同時從超過一堆火柴中拿。拿走最後一根火柴的遊戲者勝利。
本題的遊戲稍微有些不同:在第乙個回合中,第乙個遊戲者可以直接拿走若干個整堆的火柴。可以一堆都不拿,但不可以全部拿走。第二回合也一樣,第二個遊戲者也有這樣一次機會。從第三個回合(又輪到第乙個遊戲者)開始,規則和nim遊戲一樣。
如果你先拿,怎樣才能保證獲勝?如果可以獲勝的話,還要讓第一回合拿的火柴總數盡量小。
首先我們得知道博弈問題中乙個重要的東西:sg函式
我們知道,對於該遊戲,若當前取火柴方面對的是sg值為0(現有火柴的數字xor起來),且他不能通過取出某幾堆火柴使剩餘的火柴sg值為0,那麼他必敗。
證明:對於不能整堆取的石子遊戲,若sg值為0,則為必敗態(可看搜尋sg函式證明),那麼若a現在面對sg值為0的狀態時,他要想贏,只能通過移去某些堆使得對手sg值為0且對方不能使sg為0,才能必勝。(由此看來,必定存在先手必勝態)
由於要先手必勝,則要求我們使得對方面對sg為0,且對方不能使sg為0,而且要取得數量最少。
這裡我們要引入乙個概念:線性無關,若集合a中每個元素,都不能通過其他元素xor(這裡是xor,但有時候不一定是這個,具體可度娘)起來得到,則說明集合a裡的元素線性無關。
這樣,我們就把題目轉化成,求帶權線性無關集合最大值,那麼我們怎樣做呢?
首先將權值從大到小排序,每次試著將每個權值插入集合裡,然後用類似高斯消元的方法(xor),從高位到低位(二進位制)消掉該權值二進位製上的1,若最後得到的數大於0,則說明該數與該集合線性無關,將消完的數加入集合裡,ans加上原權值。
最後答案等於總火柴數減去ans
貼**
#include
#include
#include
#define n 101
using
namespace
std;
int n;
long
long ans;
int a[n];
long
long d[n];
void init()
bool did(long
long x)
void work()
void write()
int main()
GDOI2016模擬8 21新數獨
題目 下面是乙個沒有數字,只有大小關係 沒錯!那些尖角都是 大於 符號!的數獨 除了大小關係外 注意相鄰格仔不能相同 還需要滿足通常的數獨規則 l 每個格仔都是1 9 的數字 l 每行都是1 9的排列 l 每列都是1 9的排列 l 每個3 3的子矩陣 上圖中用粗線隔開,一共有3 3個這樣的子矩陣 都...
GDOI2016模擬8 8旋轉
alice和bob發明了乙個新的旋轉遊戲。首先,bob給定n個數組成的序列,並把該序列平均分配成若干個塊,每塊正好包含k個數 k能整除n 第一塊由第1到第k個數構成,第二塊由第k 1個數到第2k個數構成,以此類推。接著,bob要求alice對這個序列進行一系列操作,操作有以下兩種 1.把每塊裡面的數...
GDOI2016模擬8 13總結
這次考差了。但事後想了一下,感覺收穫好大。匯報做題情況 當然,裡面不包含收穫 第一題 我的暴力爆零了,原因又是爆int 做題過程中我想到了與眾不同的演算法,一般人會化簡不等式變成斜率優化做,但由於我對斜率優化不大敏感,而且一般斜率優化的題目都是用凸包 叉積來做,這題我也同樣想著用凸包做,但打完發現有...