﻿<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/"><channel><title>C++博客-广交天下ACM爱好者-文章分类-Game Problem</title><link>http://www.cppblog.com/goAheadtw/category/15893.html</link><description>haha</description><language>zh-cn</language><lastBuildDate>Wed, 19 Jan 2011 03:26:50 GMT</lastBuildDate><pubDate>Wed, 19 Jan 2011 03:26:50 GMT</pubDate><ttl>60</ttl><item><title>Fibonacci Nim (斐波那契取石子博弈)</title><link>http://www.cppblog.com/goAheadtw/articles/138753.html</link><dc:creator>tw</dc:creator><author>tw</author><pubDate>Tue, 18 Jan 2011 07:25:00 GMT</pubDate><guid>http://www.cppblog.com/goAheadtw/articles/138753.html</guid><wfw:comment>http://www.cppblog.com/goAheadtw/comments/138753.html</wfw:comment><comments>http://www.cppblog.com/goAheadtw/articles/138753.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/goAheadtw/comments/commentRss/138753.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/goAheadtw/services/trackbacks/138753.html</trackback:ping><description><![CDATA[<p><a href="http://creativecommons.org/licenses/by/3.0/deed.zh" target=_blank><font color=#889da1>版权声明</font></a>：转载时请以超链接形式标明文章原始出处和作者信息及<a href="http://bangzhuzhongxin.blogbus.com/logs/11205960.html" target=_blank><font color=#889da1>本声明</font></a><br><a href="http://yjq24.blogbus.com/logs/46150651.html"><font color=#889da1>http://yjq24.blogbus.com/logs/46150651.html</font></a><br><font color=#0080ff size=2 face=新宋体><br>有一堆个数为n的石子，游戏双方轮流取石子，满足：</font></p>
<p><font color=#0080ff size=2 face=新宋体>1)先手不能在第一次把所有的石子取完；</font></p>
<p><font color=#0080ff size=2 face=新宋体>2)之后每次可以取的石子数介于1到对手刚取的石子数的2倍之间（包含1和对手刚取的石子数的2倍）。</font></p>
<p><font color=#0080ff size=2 face=新宋体>约定取走最后一个石子的人为赢家，求必败态。</font></p>
<p>这个和之前的<a href="http://yjq24.blogbus.com/logs/42826226.html"><u><font color=#ff0000 size=2>Wythoff&#8217;s Game</font></u></a>和<a href="http://yjq24.blogbus.com/logs/42455293.html"><u><font color=#ff0000 size=2>取石子游戏</font></u></a>有一个很大的不同点，就是游戏规则的动态化。之前的规则中，每次可以取的石子的策略集合是基本固定的，但是这次有规则2：一方每次可以取的石子数依赖于对手刚才取的石子数。</p>
<p>这个游戏叫做Fibonacci Nim，肯定和Fibonacci数列：1,2,3,5,8,13,21,34,55,89,&#8230;有密切的关系。如果试验一番之后，可以猜测：先手胜当且仅当n不是Fibonacci数。必败态构成Fibonacci数列。</p>
<p>就像&#8220;Wythoff博弈&#8221;需要&#8220;Beatty定理&#8221;来帮忙一样，这里需要借助&#8220;Zeckendorf定理&#8221;（齐肯多夫定理）：任何正整数可以表示为若干个不连续的Fibonacci数之和。定理的证明可以在<a href="http://zh.wikipedia.org/wiki/%E9%BD%8A%E8%82%AF%E5%A4%9A%E5%A4%AB%E5%AE%9A%E7%90%86"><u><font color=#ff0000 size=2>这里</font></u></a>看到，不过我觉得更重要的是自己动手分解一下。</p>
<p>比如，我们要分解83，可以写成83=55+28，而28=21+7，7=5+2，故83=55+21+5+2；</p>
<p>如果n=83，我们看看这个分解有什么指导意义：假如先手取2颗，那么后手无法取5颗或更多，而5是一个Fibonacci数，如果猜测正确的话，（面临这5颗的先手实际上是整个游戏的后手）那么一定是先手取走这5颗石子中的最后一颗，而这个我们可以通过第二类归纳法来绕过，同样的道理，接下去先手取走接下来的后21颗中的最后一颗，再取走后55颗中的最后一颗，那么先手赢。</p>
<p>反过来如果n是Fibonacci数，比如n=89：如果先手第一次取的石子不小于34颗，那么一定后手赢，因为89-34=55=34+21&lt;2*34，所以只需要考虑先手第一次取得石子数&lt;34即可，于是剩下的石子数x介于55到89之间，它一定不是一个Fibonacci数，于是我们把x分解成Fibonacci数：x=55+f[i]+&#8230;+f[j]，如果f[j]&lt;=先手一开始所取石子数y的两倍，那么对B就是面临x局面的先手，所以根据之前的分析，B只要先取f[j]个即可，以后再按之前的分析就可保证必胜。</p>
<p><font color=#000000 size=2>下证：f[j]&lt;=2y</font></p>
<p><font color=#000000 size=2>反证法：假设f[j]&gt;2y，则 y&lt;f[j]/2=(f[j-1]+f[j-2])/2&lt;f[j-1]</font></p>
<p><font color=#000000 size=2>从而 f[k]=x+y&lt;f[k-1]+f[i]+&#8230;+f[j]+f[j-1]&lt;=f[k-1]+f[i]+f[i-1]&lt;=f[k-1]+f[k]=f[k]，矛盾。</font></p>
<img src ="http://www.cppblog.com/goAheadtw/aggbug/138753.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/goAheadtw/" target="_blank">tw</a> 2011-01-18 15:25 <a href="http://www.cppblog.com/goAheadtw/articles/138753.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>