[CQOI2013]新Nim遊戲
阿新 • • 發佈:2018-01-31
回合 class bre 最大的 證明 tput 沒有 屬於 cstring
第一行為整數k。即火柴堆數。第二行包含k個不超過109的正整數,即各堆的火柴個數。
5 5 6 6 5 5
Description
傳統的Nim遊戲是這樣的:有一些火柴堆,每堆都有若幹根火柴(不同堆的火柴數量可以不同)。兩個遊戲者輪流操作,每次可以選一個火柴堆拿走若幹根火柴。可以只拿一根,也可以拿走整堆火柴,但不能同時從超過一堆火柴中拿。拿走最後一根火柴的遊戲者勝利。 本題的遊戲稍微有些不同:在第一個回合中,第一個遊戲者可以直接拿走若幹個整堆的火柴。可以一堆都不拿,但不可以全部拿走。第二回合也一樣,第二個遊戲者也有這樣一次機會。從第三個回合(又輪到第一個遊戲者)開始,規則和Nim遊戲一樣。 如果你先拿,怎樣才能保證獲勝?如果可以獲勝的話,還要讓第一回合拿的火柴總數盡量小。Input
Output
輸出第一回合拿的火柴數目的最小值。如果不能保證取勝,輸出-1。Sample Input
65 5 6 6 5 5
Sample Output
21HINT
k<=100
可知異或和為0則必敗,也就是說開頭取掉幾堆後,剩余集合不能出現異或為0的子集
可知就是維護一個權值和最大的線性無關組(線性基)
從大到小排序,一個個加入線性基
如果沒有成功插入,那麽說明該元素與其他線性相關,即可以用線性基中的子集異或和表示
這和元素的貪心很像
給出擬陣證明
我們設n個火柴堆的數目為集合S,若某個S的子集r不存在任何一個非空子集異或和0,則r∈I.下面我們證明二元組M=(S,I)是一個擬陣。
遺傳性:設A∈I,則A是S的線性無關組,則A的任意非空子集均線性無關,即對A的任意子集B,B均線性無關,因此B∈I,證畢。
交換性:設A,B∈I,且|A|<|B|,我們要證明存在x∈B,使得A∪{x}∈I.利用反證法,假設對於任意x∈B-A,均有A∪{x}不屬於I,則B-A中的元素均在A的異或空間中,可由A的子集異或和表示。
因此B中的元素都在A的異或空間中。那麽必然有B的異或空間包含於A的異或空間。由|A|<|B|且A,B線性無關,顯然矛盾。因此交換性存在,證畢。
1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<algorithm> 5 #include<cmath> 6 using namespace std; 7 typedef long long lol; 8 int P[40],a[101],n; 9 lol ans; 10 int add(int x) 11 {int i; 12 for (i=30;i>=0;i--) 13 if (x&(1<<i)) 14 { 15 if (P[i]==0) 16 { 17 P[i]=x; 18 break; 19 } 20 x^=P[i]; 21 } 22 return x; 23 } 24 int main() 25 {int i; 26 cin>>n; 27 for (i=1;i<=n;i++) 28 scanf("%d",&a[i]); 29 sort(a+1,a+n+1); 30 for (i=n;i>=1;i--) 31 { 32 if (add(a[i])==0) ans+=a[i]; 33 } 34 cout<<ans; 35 }
[CQOI2013]新Nim遊戲