【博弈】之斐波那契博弈

///2019博弈
///已知n为必胜点(题目说到n就胜利),所以我们进行倒推,
///我们首先将考虑n-1到n/2+1这一段,例如n=10
///那么n-1到n/2+1就是,6到9,因为这一段我们不需要考虑题目所说的2*i;只能走一步;
///所以我们可以从n为必胜点倒推回去其他点的状态。
///然后来到1——n/2;这里的点i,可以走两条路,要么i+1要么i*2,所以我们可以从这两点倒退回去
///其中一个点为必胜,那么i就是必败点,因为下一个人就可以从这个点到必胜点。
///所以我们就可以进行打表,然后发现规律,再在oeis找规律,然后发现cuber win的时候的序列关系的关系是
///a[2*n]=a[n]*4,a[2*n+1]=a[n]*4+2;

 

打表代码:

 1 #include<bits/stdc++.h>
 2 #define numm ch-48
 3 using namespace std;
 4 template <typename T>
 5 void read(T &res) {
 6     bool flag=false;char ch;
 7     while(!isdigit(ch=getchar())) (ch=='-')&&(flag=true);
 8     for(res=numm;isdigit(ch=getchar());res=(res<<1)+(res<<3)+numm);
 9     flag&&(res=-res);
10 }
11 template <typename T>
12 void write(T x) {
13     if(x<0) putchar('-'),x=-x;
14     if(x>9) write(x/10);
15     putchar(x%10+'0');
16 }
17 typedef pair<int,int> pi;
18 typedef long long ll;
19 const int maxn=10010;
20 int a[maxn];
21 int main()
22 {
23     int n;
24     #define local
25     #ifdef local
26         freopen("1.txt","w",stdout);
27     #endif
28 
29     #define p1 puts("Little Fang Win")
30     #define p2 puts("Cuber QQ Win")
31     for(int j=2;j<=10000;j++) {
32         n=j;
33         if(n==1) {
34             p1;
35             continue;
36         }
37         if(n%2) {
38             a[n]=1;
39             n--;
40             a[n]=0;
41             for(int i=n-1;i>n/2&&i>1;i--)
42                 if((n-i)%2) a[i]=1;
43                 else a[i]=0;
44         }
45         else {
46             a[n]=1;
47             for(int i=n-1;i>n/2&&i>1;i--)
48                 if((n-i)%2) a[i]=0;
49                 else a[i]=1;
50 
51         }
52         for(int i=n/2;i>1;i--)
53             a[i]=max(a[i*2],a[i+1])?0:1;
54         if(a[2]) write(j),cout<<"->",p2;
55     }
56     return 0;
57 }

 

posted on 2019-09-12 00:06  师姐的迷弟  阅读(268)  评论(0编辑  收藏  举报

导航