大型网站制作,手机版网站 html5,泰州市建设监理协会网站,小学学校网站设计模板Alice and Bob
题意#xff1a;
两人博弈#xff0c;每次一个人从一堆中拿k个#xff0c;同时从另一堆拿k * s(s0)个#xff0c;问谁先不能拿 10000组数据,N5000
题解#xff1a;
(x,y)表示第一堆石头数量为x#xff0c;第二堆为y 如果(x,y)是必败状态#…Alice and Bob
题意
两人博弈每次一个人从一堆中拿k个同时从另一堆拿k * s(s0)个问谁先不能拿 10000组数据,N5000
题解
(x,y)表示第一堆石头数量为x第二堆为y 如果(x,y)是必败状态那么通过取走石头一次直接形成(x,y)的(x1,y1)必然不是必败状态
如果(x,y)不是必败状态那(x1,y1)就不一定了 可以通过反证去理解 指向必败状态的是必胜状态必胜状态可以指向必败也可以指向必胜。必败状态无法到必败状态
综上我们只需要关注一个点是否可以由必败点得到如果可以该点不是必败点否则是必败点
此时复杂度为O(n4),但是要知道一个结论对于一个的i只存在至多一种j后手能够获胜 证明如下 若存在iqippq满足后手胜那么Alice只需将ip-iq即可获胜不满足后手胜的条件。 这样复杂度就大约在O(n3)
代码
#includeiostream
#includestdio.h
using namespace std;
bool f[5001][5001];
int main()
{ for(int i0;i5000;i)//自小到大枚举ijfor(int j0;j5000;j){if(f[i][j]0)//对于每种必败态进行拓展{for(int k1;ki5000;k)for(int s0;s*kj5000;s)f[ik][js*k]1;for(int k1;kj5000;k)for(int s0;s*ki5000;s)f[is*k][jk]1;}}int t,n,m;cint;while(t--){scanf(%d%d,n,m);if(f[n][m]0){puts(Bob);}else puts(Alice);}return 0;
}