这是一道坑比的博弈题。。。
尽管这道题实现起来很简单,但是思考的过程很有意义。
先从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步:
①从最简单的方案入手研究。
②把范围扩大,推出公式。
③实现程序并优化。