jzoj3033. 【NOIP2012模拟10.17】石子游戏

本文深入探讨了一种基于博弈论的游戏策略,通过分析不同参数K下必败状态的规律,提出了有效的胜出策略。从简单的K=1和K=2案例出发,逐步推导出一般情况下如何构建数列以确保胜利的方法。

这是一道坑比的博弈题。。。

尽管这道题实现起来很简单,但是思考的过程很有意义。

先从K=1的情况入手:

因为对方每次拿的数量都不能超过你上次拿的数量,所以可以得出必败结果都是2^i

思考:

可以把N转成二进制,例如N=25

则N(2)=11001

那么我们每次拿掉最末尾的一个1,则对方不能拿更高层的1。

拿完后N=24 (11000)

这样我们每一次都拿走最末尾的1,对方就只能拿0。

对方拿完后N=23 (10111)

而对方每次拿完0后又会产生新的1,一直到最后一个1被我们拿走。

必败情况就是2^i,例如:

N=32 (100000)

因为不能一次性拿完,那么我们只能拿走0,对方就可以每次拿走末尾的1。

K=2的情况:

必败结果为斐波那契数列

思考:

因为斐波那契数列有一个性质:把任意一个数N分解成数列中的数相加,分解出的数两两都至少相差2倍以上(注意是以上)

所以我们只要把N分解成斐波那契数列,之后像K=1的情况一样计算。

其实K=1和K=2的情况的性质都是一样的。

因为K=1时分解的数列为2^i,即1 2 4 8 16 32 64……

K=2时斐波那契数列为1 2 3 5 8 13 21 34 55……

↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑没看懂上两种情况请重新再看直到看懂为止↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑

↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑如果只想水30分的话就可以到此为止了↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑↑

K>2的情况:

根据上面的两种情况,我们可以发现:

当K不同时,只是分解出的数列不同,计算其实是一样的。

那么我们只要计算出一个序列,用这个序列的数相加来表示N,并且每两个数都要相差K倍以上。

思考:

假设K=3,N=35。

先计算N=1

因为序列为空,所以第一项是1。

N=2

因为序列中只有1,所以第二项是2。

如此类推,第三项是3。

N=4

尽管1+3=4,但是因为1*3≥3,所以无法构成合法的序列,第四项为4。

如此类推,该序列为1 2 3 4 6 8 11 15……

而1+4+15=20,所以下一项是21。

补充:如果当前序列最大能构成N,即能构成1~N中任意一个数。

又如此类推,该序列为1 2 3 4 6 8 11 15 21 29 40……

最后一项已经比N大了,可以不用继续往下算了。

因为40≠35,所以可以获胜。

之后把N一直往下减,减到N=当前项。

答案就是当前位置对应的数,即7。

但是考虑到时间的问题,如果该序列有多项就要一个一个去减,时间就可能会爆。

设当前K计算出的序列为A,则用B[i]表示从1~i序列中能构成的最大数。

显然A[i]=B[i-1]+1,A[1]=1且B[1]=1。

之后计算B[i],找到一个最大的j,且A[j]*k<A[i]

因为当前的B[i]等于最大且和当前项的倍数不超过K的数所能构成的最大数,再加上当前数,

所以B[i]=B[j]+A[i]。

最后补充:

假设当前所构成的序列为A,把A再加上一个数所能构成的最大数肯定比原来的序列A构成的数大,

所以枚举J这一步是线性的。

这道题想了我挺久的,把题解反复看了之后才想出来的。

总之,解决此类问题有3步:

①从最简单的方案入手研究。

②把范围扩大,推出公式。

③实现程序并优化。


作者:gmh77
来源:优快云
原文:https://blog.youkuaiyun.com/gmh77/article/details/52650067
版权声明:本文为博主原创文章,转载请附上博文链接!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值