博弈学习(三) HDU 1538 A Puzzle for Pirates(经典的海盗分金推理)



转载请注明出处,谢谢 http://blog.csdn.net/ACM_cxlove?viewmode=contents           by---cxlove

题目:这是一个经典问题,有n个海盗,分m块金子,其中他们会按一定的顺序提出自己的分配方案,如果50%以上的人赞成,则方案通过,开始分金子,如果不通过,则把提出方案的扔到海里,下一个人继续。

http://acm.hdu.edu.cn/showproblem.php?pid=1538

首先我们讲一下海盗分金决策的三个标准:保命,拿更多的金子,杀人,优先级是递减的。

同时分为两个状态稳定状态和不稳定状态:如果当n和m的组合使得最先决策的人(编号为n)不会被丢下海, 即游戏会立即结束, 就称这个状态时"稳定的". 反之, 问题会退化为n-1和m的组合, 直到达到一个稳定状态, 所以乘这种状态为"不稳定的".

接下来我们从简单的开始分析:
如果只有两个人的话:那么2号开始提出方案,这时候知道不管提什么,他自己肯定赞成,过半数,方案通过,那么2号肯定把所有的金子都给了自己。
如果只有三个人的话:那么3号知道,如果自己死了,那么2号肯定能把所有金子拿下,对于1号来说没有半点好处。
那么他就拿出金子贿赂1号,1号拿到1个金子,总比没有好,肯定赞成3号,剩下的3号拿下。
如果只有四个人的话:那么4号知道,如果自己死了,那么1号拿到1个金子,2号什么都没有,3号拿下剩下的金子。
那他就可以拿出部分金子贿赂2号,2号知道如果4号死了,自己将什么都没有,他肯定赞成4号。
如此类推下去,貌似就是第一个决策的时候,与他奇偶性相同的人会被贿赂拿到1个金子,剩下的全归提出方案的人所有。

但是会有一个问题便是,如果金子不够贿赂怎么办。
情况1、我们首先归纳之前的,如果n<=2*m时候,前面与n相同奇偶性的得到1个金子,剩下的第n个人拿下。
情况2、如果n==2*m+1,第n个人拿出m个金子贿赂前面的m个人。自己不拿金子,这样刚好保证自己不死,这就是之前提到的优先级,首先得保命,如果自己拿了一个金子,那么前面就有一个人会反对,因为对于那个人,不管怎么样都分不到金子,则轮到第三个原则,杀人,肯定投反对票。

剩下来我们考虑,钱不够贿赂的情况:
我们将问题具体化:如果有500个海盗,只有100个金子,那么前面201个已经分析过了。
对于202号来说,自己不能拿金币,而贿赂上一轮没有拿到金币的101人中的100人就够了。
对于203号来说,需要102个人的支持,显然加上他自己,还需要101票,而金子不够贿赂,别人会反对,而达到杀人的目的。
对于204号来说,他知道一旦自己死了,203号是必死,抓住这点,203必然支持他,因为203号宁可不要金币,也要保住性命,所以204号把100个金币分给之前的100个人,然后203和他自己的两票保证自己不死。
对于205号来说,203,和204是不会支持他的,因为一旦205死了,他们不仅可以保住性命,而且还可以看着205死掉。所以205是必死
那么206呢,虽然205必死,会支持他,但是还是缺一票,所以必死。
对于207呢,205和206之前是必死,会支持他,但是加上自己以及100个贿赂名额,还是必死
对于208号,205,206.,207因为后面是必死的,肯定会支持208成功,那么208刚好能凑齐104票,得以保命。

以下我们猜想:n=2*m+2^k的情况下,是可以保命的,称为稳定状态,否则为不稳定状态,我们证明一下:
首先对于n来说,有m票贿赂,但是对于2*m+2^(k-1)以前必死的死,他们会支持2*m+2^(k-1),因为他们肯定拿不到钱,而且支持2*m+2^(k-1),另外根据杀人原则,希望之后的人都死,轮到2*m+2^(k-1)决策的时候保命就行了。
同理2*m+2^(k-1)到2*m+2^k之间的2^(k-1)-1个人来说,他们必死,所以必定支持2*m+2^k,加上m个金币贿赂的,加上他自己,刚好有m+2^(k-1)。这样刚好凑齐一半,可以不死。
证明完毕:2*m+2^k的人可以保命,否则必死。

我们考虑一下分金币情况:
情况3:对于第2*m+2^k个人来说,他可以保命,肯定分不到金子,而他手上的m个金子,可以贿赂m个人,但是具体是哪些人是不定的。则不管是不能分到金子,还是可能分不到金子的人来说,结果都为0。
情况4:对于2*m+2^(k-1)到2*m+2^k之间的来说,他们的决策是必死,而在他们决策的时候,其它人分得金币情况也为0。

我们来解释一下金币的不确定性:

金币数量的不确定性:由上面的推理可知, 当n=2m+2时, 上一轮推理没有分到金币的人的金币数量首次具有不确定性, 并且在n>2m+2时, 这种不确定性一定会延续下去, 轮到因为n号决策者之前的一个人决策时, 那个人肯定分不到金币了, 所以在上一轮推理中没有分到金币的人的个数一定大于m.

综合情况1,2,3,4便是本题的解,
代码如下:
[cpp] view plain copy print ?
  1. #include<iostream>  
  2. #include<cstdio>  
  3. #include<ctime>  
  4. #include<cstring>  
  5. #include<cmath>  
  6. #include<algorithm>  
  7. #include<cstdlib>  
  8. #include<vector>  
  9. #define C    240  
  10. #define TIME 10  
  11. #define inf 1<<25  
  12. #define LL long long  
  13. using namespace std;  
  14. //保存2的幂  
  15. int fac[15]={2,4,8,16,32,64,128,256,512,1024,2048,4096,8192,16384,32768};  
  16. void slove(int n,int m,int p){  
  17.     //金币够贿赂的情况  
  18.     if(n<=2*m){  
  19.         //不是决策者,而且奇偶性相同,都能被贿赂  
  20.         if(n!=p&&(n%2==p%2))  
  21.             printf("1\n");  
  22.         //剩下的都是决策者拥有  
  23.         else if(n==p)  
  24.             printf("%d\n",m-(n-1)/2);  
  25.         else  
  26.         //其余人分不到金币,他们的决策不影响全局  
  27.             printf("0\n");  
  28.         return ;  
  29.     }  
  30.     //这时候的不同在于决策者不能拿金币  
  31.     else if(n==2*m+1){  
  32.         if(p<2*m&&p&1)  
  33.             printf("1\n");  
  34.         else  
  35.             printf("0\n");  
  36.         return ;  
  37.     }  
  38.     int t=n-2*m,i;  
  39.     //这是刚好保命的情况,对于决策者来说,肯定没有金币  
  40.     //对于其它人来说,要么肯定没有金币,要么可能没有金币,不确定性  
  41.     for( i=0;i<14;i++){  
  42.         if(t==fac[i]){  
  43.             printf("0\n");  
  44.             return;  
  45.         }  
  46.     }  
  47.     for( i=1;i<14;i++)  
  48.         if(t<fac[i]){  
  49.             //决策者必死  
  50.             if(p>2*m+fac[i-1]&&p<2*m+fac[i])  
  51.                  printf("Thrown\n");  
  52.             else  
  53.                  printf("0\n");  
  54.             return ;  
  55.         }  
  56. }  
  57. int main(){  
  58.     int t,n,m,p;  
  59.     scanf("%d",&t);  
  60.     while(t--){  
  61.         scanf("%d%d%d",&n,&m,&p);  
  62.         slove(n,m,p);  
  63.     }  
  64.     return 0;  
  65. }  

你可能感兴趣的:(博弈学习(三) HDU 1538 A Puzzle for Pirates(经典的海盗分金推理))