HDU 1538 A Puzzle for Pirates (海盗分金问题)

A Puzzle for Pirates

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)
Total Submission(s): 508    Accepted Submission(s): 167

Problem Description

A bunch of pirates have gotten their hands on a hoard of gold pieces and wish to divide the loot. They are democratic pirates in their own way, and it is their custom to make such divisions in the following manner: The fiercest pirate makes a proposal about the division, and everybody votes on it, including the proposer. If 50 percent or more are in favor, the proposal passes and is implemented forthwith. Otherwise the proposer is thrown overboard, and the procedure is repeated with the next fiercest pirate. 
All the pirates enjoy throwing one of their fellows overboard, but if given a choice they prefer cold, hard cash, the more the better. They dislike being thrown overboard themselves. All pirates are rational and know that the other pirates are also rational. Moreover, no two pirates are equally fierce, so there is a precise pecking order — and it is known to them all. The gold pieces are indivisible, and arrangements to share pieces are not permitted, because no pirate trusts his fellows to stick to such an arrangement. It‘s every man for himself. Another thing about pirates is that they are realistic. They believe ‘a bird in the hand is worth two in the bush‘ which means they prefer something that is certain than take a risk to get more, where they might lose everything.

For convenience, number the pirates in order of meekness, so that the least fierce is number 1, the next least fierce number 2 and so on. The fiercest pirate thus gets the biggest number, and proposals proceed in the order from the biggest to the least.

The secret to analyzing all such games of strategy is to work backward from the end. The place to start is the point at which the game gets down to just two pirates, P1 and P2. Then add in pirate P3, P4, ... , one by one. The illustration shows the results when 3, 4 or 5 pirates try to divide 100 pieces of gold.

Your task is to predict how many gold pieces a given pirate will get.

Input

The input consists of a line specifying the number of testcases, followed by one line per case with 3 integer numbers n, m, p. n (1 ≤ n ≤ 10^4) is the number of pirates. m (1 ≤ m ≤ 10^7) is the number of gold pieces. p (1 ≤ p ≤ n) indicates a pirate where p = n indicates the fiercest one.

Output

The output for each case consists of a single integer which is the minimal number of gold pieces pirate p can get. For example, if pirate p can get 0 or 1 gold pieces, output ‘0‘. If pirate p will be thrown overboard, output ‘Thrown‘.

Sample Input

3

3 100 2

4 100 2

5 100 5

Sample Output

0

1

98

Hint

Hint

The situation gets complicated when a few gold pieces were divided among many pirates.

Author

Otter

Source

TJU Contest August 2006

本文转自:http://blog.csdn.net/ACM_cxlove?viewmode=contents

题目:这是一个经典问题,有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便是本题的解,

#include<iostream>
#include<cstdio>
#include<ctime>
#include<cstring>
#include<cmath>
#include<algorithm>
#include<cstdlib>
#include<vector>
#define C    240
#define TIME 10
#define inf 1<<25
#define LL long long
using namespace std;
//保存2的幂
int fac[15]={2,4,8,16,32,64,128,256,512,1024,2048,4096,8192,16384,32768};
void slove(int n,int m,int p){
    //金币够贿赂的情况
    if(n<=2*m){
        //不是决策者,而且奇偶性相同,都能被贿赂
        if(n!=p&&(n%2==p%2))
            printf("1\n");
        //剩下的都是决策者拥有
        else if(n==p)
            printf("%d\n",m-(n-1)/2);
        else
        //其余人分不到金币,他们的决策不影响全局
            printf("0\n");
        return ;
    }
    //这时候的不同在于决策者不能拿金币
    else if(n==2*m+1){
        if(p<2*m&&p&1)
            printf("1\n");
        else
            printf("0\n");
        return ;
    }
    int t=n-2*m,i;
    //这是刚好保命的情况,对于决策者来说,肯定没有金币
    //对于其它人来说,要么肯定没有金币,要么可能没有金币,不确定性
    for( i=0;i<14;i++){
        if(t==fac[i]){
            printf("0\n");
            return;
        }
    }
    for( i=1;i<14;i++)
        if(t<fac[i]){
            //决策者必死
            if(p>2*m+fac[i-1]&&p<2*m+fac[i])
                 printf("Thrown\n");
            else
                 printf("0\n");
            return ;
        }
}
int main(){
    int t,n,m,p;
    scanf("%d",&t);
    while(t--){
        scanf("%d%d%d",&n,&m,&p);
        slove(n,m,p);
    }
    return 0;
}

时间: 2024-10-03 22:03:22

HDU 1538 A Puzzle for Pirates (海盗分金问题)的相关文章

HDU 1538 A Puzzle for Pirates 经典海盗分金币

题目:这是一个经典问题,有n个海盗,分m块金子,其中他们会按一定的顺序提出自己的分配方案,如果50%以上的人赞成,则方案通过,开始分金子,如果不通过,则把提出方案的扔到海里,下一个人继续. 首先我们讲一下海盗分金决策的三个标准:保命,拿更多的金子,杀人,优先级是递减的. 同时分为两个状态稳定状态和不稳定状态:如果当n和m的组合使得最先决策的人(编号为n)不会被丢下海, 即游戏会立即结束, 就称这个状态时"稳定的". 反之, 问题会退化为n-1和m的组合, 直到达到一个稳定状态, 所以乘

海盗分金问题(博弈)

NBUOJ 2680:海盗分金 题意: 有N个海盗要分M金币,将N个海盗从1-N编号,由第一个人提出分配方案,一人一票(分配者也拥有一票),超过半数同意方案才被通过,否则他将被扔入大海喂鲨鱼,接下来由下一人分配,以此类推. 分析:从3个人的状态往后推,每次处理出当前分配方案下的被分到0,1 金币的海盗数量,当前被分到0,下次并然分到1,当前分到1的判断是否需要分配2才能满足通过条件,最后输出分配剩余的金币数即可. 代码: 1 #include "cstdio" 2 #include &

海盗分金的故事

两周时间,身体疲惫的要死. 近来,每晚一梦的习惯又开始了. 昨晚,睡了好久,做了很诡异的梦,把自己纠缠到醒之后,好想拿起手机问问是不是很多人都在看世界杯. 朦胧中细想,这还用问么?楼上还有声音,估计正在等待看巴西和德国大战. ---------------------------------分割线---------------------------------------- 海盗分金,是一个经济学问题.整个故事喜感到爆,原理是用最小代价获取最大利益.但,前提是每个人都必须是智商高到爆. 假如任

海盗分金的问题

海盗分金好像是个博弈论的老问题了. 本科的时候听GXL谈到过问题本身,没有去解.昨天,LX问到我这个问题.思考了一下解法,不知道对不对,写在这里. 流行的问题是这样: 五个海盗抢到了100枚金币,他们决定这么分: 1.抽签决定自己的号码 :5  4  3  2  1: 2.首先,由5号提出分配方案,然后5人共同进行表决,如果有半数或半数以上人同意时,就按照他的提案进行分配,否则5号将被扔入大海喂鲨鱼: 3.在5号死后,由4号提出分配方案,然后4人进行表决,如果有半数或半数以上人同意时,就按照他的

海盗分金问题SQL求解(贪心算法)

问题 经济学上有个"海盗分金"模型:是说5个海盗抢得100枚金币,他们按抽签的顺序依次提方案:首先由1号提出分配方案,然后5人表决,超过半数同意方案才被通过,否则他将被扔入大海喂鲨鱼,依此类推,假设海盗是足够聪明的先利己再伤人,最后方案是怎样的? 网上百度来的的代码 with a as (select 101 - rownum n from dual connect by rownum <102), max_one as (select max(n) max1 from a),

算法浅谈——递归算法与海盗分金问题

本文始发于个人公众号:TechFlow 最近看到一道很有意思的问题,分享给大家. 还是老规矩,在我们聊算法问题之前,先来看一个故事. 传说中,有5个海盗组成了一支无敌的海盗舰队,他们在最后一次的寻宝当中找寻到了100枚价值连城的金币.于是,很自然的,这群海盗面临分赃的问题.为了防止海盗内讧,残忍的海盗们制定了一个奇怪的规则: 他们决定按照功劳大小对五个人进行编号,由编号小的海盗先提出分配方案.如果方案能够得到大多数人的同意,那么就按照他提出的方案进行分配.如果不能通过,说明他已经失去了威望,海盗

NYOJ 994 海盗分金 逆向递推

链接:http://acm.nyist.net/JudgeOnline/problem.php?pid=994 题意: 有n个海盗劫得了窖藏的m块金子,并准备瓜分这些战利品.按照古老流传下来的分金法则,由最厉害的一名海盗提出一个分金方案,假如有不小于一半的海盗(包括自己)支持这个方案,则按这个方案分,否则把这个海盗扔进海里,重复由下一个厉害的海盗提出方案. 大家都知道,所有海盗都是贪婪的,虽然他们都乐于看到自己的同伴被扔进海里,但是他们还是希望在保命的前提下分的最多的金子,现在已经按海盗的厉害程

海盗分金

/* 5个海盗抢到了100颗宝石,每一颗都一样的大小和价值. 他们决定这么分: 1.抽签决定自己的号码(1,2,3,4,5) 2.首先,由1号提出分配方案,然后大家5人进行表决,当且仅当半数和超过半数的人同意时,按照他的提案进行分配,否则将被扔入大海喂鲨鱼. 3.如果1号死后,再由2号提出分配方案,然后大家4人进行表决,当且仅当半数和超过半数的人同意时,按照他的提案进行分配,否则将被扔入大海喂鲨鱼. 4.以次类推...... 条件: 每个海盗都是很聪明的人,都能很理智的判断得失,从而做出选择.

好玩的智力小游戏(海盗分金)

 海盗的难题(Ian Stewart) 数学的逻辑有时会导致看来十分怪异的结论. 一般的规则是.假设逻辑 推理没有漏洞. 那么结论就必然站得住脚,即使它与你的直觉矛盾. 1998 年9月,加利福尼亚州帕洛阿 尔托的Stephen M. Omohundro寄给我一道难题, 它恰好就属于这一类.这难题已经流传 了至少十年,可是Omohundro对它作 了修改,使它的逻辑问题变得分外复杂了. 先来看看此难题原先的形状. 10名海盗抢得了窖藏的100块金子,并打算 瓜分这些战利 品.这是一些讲民主的