[K倍动态减法问题] HDU 2486 & HDU2580 & POJ3922 a simple stone game

本文介绍了一种基于斐波那契博弈的加强版博弈策略,通过构造特殊数列来确定游戏胜负条件及最优策略。对于不同参数K,文章给出了后手必胜条件及其对应的先手策略。

开发板推荐:天空星STM32F407VET6开发板

超高性价比 STM32主控 | 超高主频 | 一板兼容百芯 | 比赛神器 | 沉金彩色丝印

这就是斐波那契博弈的加强版
对于某些特定的K 我们有结论

  • K=1 后手必胜当且仅当n2的次幂 先手的策略是取lowbit(n)
    • K=2 后手必胜当且仅当n是斐波那契数 先手的策略是取n的斐波那契拆分中最小的数

    这道题 我们仿照斐波那契博弈的构造方法
    构造一个数列an
    将每个自然数都表示成an中不连续的几项的和 f1+f2++fn
    数列fnfj+1>Kfj 即满足题中的k倍关系

    • 如果该堆石子恰是数列an中的一项 后手必胜
    • 否则 该堆石子可以表示为an中的不连续几项的和 先手必胜 策略是取其中f1个石子 后手取走的石子不会超过f2个 继续上述策略 后手永远取不完石子

    下面程序中 a即表示这个序列 b作为辅助数组表示前i个的a能够按规则构造出的最大的数

    #include<cstdio>
    #include<cstdlib>
    #include<algorithm>
    #define read(x) scanf("%d",&(x))
    using namespace std;
    
    const int N=5000005;
    int n,K,a[N],b[N];
    
    int main(){
      int T,Case=0;
      freopen("t.in","r",stdin);
      freopen("t.out","w",stdout);
      read(T);
      while (T--){
        read(n); read(K);
        int x=0,y=0;
        while (a[x]<n){
          a[++x]=b[x-1]+1;
          while (a[y+1]*K<a[x]) y++;
          if (a[y]*K<a[x])
        b[x]=b[y]+a[x];
          else
        b[x]=a[x];
        }
        printf("Case %d: ",++Case);
        if (n==a[x]) printf("lose\n");
        else{
          int ans;
          for (;n;x--) if (n>=a[x]) n-=a[x],ans=a[x];
          printf("%d\n",ans);
        }
      }
      return 0;
    }
    

开发板推荐:天空星STM32F407VET6开发板

超高性价比 STM32主控 | 超高主频 | 一板兼容百芯 | 比赛神器 | 沉金彩色丝印

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值