您的位置:首页 > 其它

数学专题---博弈论【更新中】

2016-05-23 20:08 232 查看
1.从nim游戏讲博弈论

考虑这样一个游戏,有三堆火柴,记为(a,b,c),每次可以在一堆中取任意根,也可以都拿走,但不能从多个堆中同时拿,无火柴可拿的人输.

我们可以推导出sg函数,SG(x)=x,根据SG定理,x1^x2^…..^xn=0则一定输

那么当游戏不是nim游戏的时候,如何确定胜负关系呢

例题1. hdu153

原题

题意:跟nim游戏一样,但不可以取任意根,只能取k根火柴,k属于集合限定集合s。

题解:因为数据范围很小,递推求SG函数,找到最小的不能达到的状态

再取亦或。

代码:

int T,k,i,n,m,j,x,y,z,ans;

int s[10005];
int d[105];

int get(int x)
{
int mm[105];
int i;
if (s[x]!=-1) return s[x];
if (x<d[1]) return s[x]=0;
Fill(mm,0);
FOR(i,k)
{
if(d[i]>x) break;
mm[get(x-d[i])]=1;

}
REP(i,0,10005) {if (mm[i]==0) {return s[x]=i;}}
}

int main()
{
offcin;
while(cin>>k&&k){
FOR(i,k) cin>>d[i];
sort(d+1,d+k+1);
Fill(s,-1);
cin>>T;
get(4);
FOR(j,T)
{
cin>>n;
ans=0;
fori {cin>>x; ans^=get(x);}
if(ans==0) cout<<"L"; else cout<<"W";
}
cout<<endl;
}
}


hdu1079

原题

题意:给一个日期,每次加一个月或者一年,不能出现不存在的日期

日期超过2001,11,4的人输

题解:简单的博弈,从必败状态开始搜,标记,写起来好像比较烦…不写了

还有巧妙的做法:

找规律,不然是月份加一,还是日期加一,都改变了奇偶性,只有两个特殊日期9月30日,和11月30日例外。

那么目标日期是11月4日,为奇数。初始日期如果为偶数的话,先者必胜。

考虑特殊是日期,两个特殊日期本来为奇数,移动一步还是奇数。那么会不会在中途经过这两个日期呢。

如果本来为偶数,如果经过特殊日期就会改变奇偶,从必胜到必败。作为先手,不会主动进入特殊日期,而后者不可能从奇数依旧到达特殊日期的奇数。

如果本来为奇数,同样先手想赢,但是不可能进入特殊日期。保持奇偶性交替变化。

这样一来只可能是初始为特殊日期,否则中途不可能出现特殊日期

HDU1847

原题

题意:n张牌,两个人,每次只能抽2的倍数张

题解:打个表就能发现,三的倍数后手赢不然先手赢

HDU2516

原题

题意:n个石子,取走最后一块的赢,每一次不能超过前一次的两倍,第一次不能都拿走

题解:著名的斐波那契FIB博弈,证明
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: