问题:
本题首先是题意的理解:第一看了几位大佬的题解结合自己的理解,题目的意思应该是选手每次取一堆石子,取完后再新添加两堆石子,并且这两堆石子的个数都要比原堆石子个数要少,但是新的这两堆石子的个数之和可以大于原堆石子个数,那么为什么本题目可以有解呢,因为每取一次新堆石子个数的最大值都要比原堆石子个数最大值要少,如此循环往复石堆一定可以被取完。
第二就是问题的求解,这里一堆石子可以分成若干种两个新子堆的状态: ax->(bi,bj),(ci,cj)……………………,(ni,nj),子状态又能分为若干子状态,这里子状态的sg值为
sg(i,j)=(sg(i)^sg(j))
代码:
#include<iostream>
#include<cstring>
#include<algorithm>
#include<unordered_set>
using namespace std;
const int N=110;
int f[N];
int sg(int x){
if(f[x]!=-1)
return f[x];
unordered_set<int>S;
for(int i=0;i<x;i++)
{
for(int j=0;j<=i;j++){ //为避免重复计算,x>i>=j
S.insert(sg(i)^sg(j));
}
}
for(int j=0;;j++){
if(!S.count(j)){
f[x]=j;
return f[x];
}
}
}
int main(){
int n;
cin>>n;
int res=0;
memset(f,-1,sizeof f);
for(int i=0;i<n;i++){
int x;
cin>>x;
res=res^sg(x);
}
if(res)
cout<<"Yes";
else{
cout<<"No";
}
return 0;
}