题目
分析
- 本题是个博弈论
- 我看其他人都是把题解co上去的
- 所以我手动分析一波
- 首先,k=1就是转成二进制
- 而k=2就是斐波那契数列
- 那就让我来论证一下k=1
- 首先现在有一个数,n=24
- 二进制是11000
- 我们取最后一个1 得到 10000
- 然后对手只能破坏我刚刚1后面的零 可能会变成10110 10010 10011
- 然后我就会去把1变成0
- 最后数就只剩下一个1给对手了,而只有一个1是肯定lose的
- 简单说就是对手添1我补0所以剩下最后一个肯定是给他的
- 然后我们来讨论一下我们k>3的数列构建问题
- 我只能口胡一下,望理解
- 首先,核心代码如下
while (a[i]<n)
{
i++;
a[i]=b[i-1]+1;
while (a[j+1]*k<a[i]) 我要找到一个刚好*k小于我当前a[i]的数
j++;
if (a[j]*k<a[i]) b[i]=b[j]+a[i]; 然后这里是干什么呢因为a[i]=b[i-1]+1,所以b[i]=b[j]+b[i-1]+1; 当是为什么我a[i]=b[i]+1呢??看下面
else b[i]=a[i];
} - 我们当k=1是不是就是二进制 比如我们的1000,破坏前边的1
- 是不是可能成为0111,那我们的0111+1不就等于1000吗
- 我们数列需要一个数是可以被另外其他多个数组组成的,那不就成立了吗
代码
1 #include<bits/stdc++.h> 2 const int MAX=2000000; 3 int a[MAX],b[MAX],n,m,C,num=0; 4 5 int main() 6 { 7 for(scanf("%d",&C);C--;) 8 { 9 scanf("%d%d",&n,&m); 10 a[0]=b[0]=1; 11 int i=0,j=0; 12 while(a[i]<n) 13 { 14 i++; 15 a[i]=b[i-1]+1; 16 while(a[j+1]*m<a[i]) j++; 17 if(a[j]*m<a[i]) b[i]=b[j]+a[i]; 18 else b[i]=a[i]; 19 } 20 printf("Case %d: ",++num); 21 if(a[i]==n) 22 { 23 puts("lose"); 24 continue; 25 } 26 int ans; 27 while(n) 28 { 29 if(n>=a[i]) n-=a[i],ans=a[i]; 30 i--; 31 } 32 printf("%d ",ans); 33 } 34 return 0; 35 }