这就是斐波那契博弈的加强版
对于某些特定的K 我们有结论
K=1 后手必胜当且仅当n是2 的次幂 先手的策略是取lowbit(n)- K=2 后手必胜当且仅当n是斐波那契数 先手的策略是取
n 的斐波那契拆分中最小的数
这道题 我们仿照斐波那契博弈的构造方法
构造一个数列an
将每个自然数都表示成an中不连续的几项的和 f1+f2+⋯+fn
数列fn中 fj+1>K∗fj 即满足题中的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; }- K=2 后手必胜当且仅当n是斐波那契数 先手的策略是取
本文介绍了一种基于斐波那契博弈的加强版博弈策略,通过构造特殊数列来确定游戏胜负条件及最优策略。对于不同参数K,文章给出了后手必胜条件及其对应的先手策略。

1075

被折叠的 条评论
为什么被折叠?



