海盗分金

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

  条件:
  每个海盗都是很聪明的人,都能很理智的判断得失,从而做出选择。

  问题:
  第一个海盗提出怎样的分配方案才能够使自己的收益最大化?

  分析:从后面开始往前计算,
考虑只有两个人:无论前一个人提出什么方案,后一个人都会否决,故当有两个人的时候前一个人必死
考虑只有三个人:第一个人知道第二个必须拥护自己(否则剩下两个人时他必死),所以他可以自己独吞所有金币,分配方案 100 0 0
考虑只有四个人:由于三个人的时候没有人会面临死亡的威胁,故第一个人必须拉拢两个人,只需要在第三个人基础上选择金币最少的
两个人分别多给其一个金币即可,分配方案98 0 1 1
.
.
.
之后的情况都是依赖于前一种情况就可以决定了,用递归可以很好解决.
  */
#include <iostream>
#include <algorithm>
using namespace std;

class node
{
public:
    int goal;
    int pos;
    node()
    {
        goal=pos=0;
    }
};
bool cmp(node a,node b)
{
    return a.goal<b.goal;
}
bool cmp2(node a,node b)
{
    return a.pos<b.pos;
}
class heap
{
public:
    node *p;
    node *res;
    int n;
    heap()
    {
        p=NULL;
        res=NULL;
        n=0;
    }
    void copy()
    {
        node *tem =new node[n];
        for(int i=0;i<n;i++)
            tem[i]=res[i];
        delete[] p;
        p=tem;
    }

    void rebuild(int i)
    {
        node *temp = new node[i];
        delete[] res;
        res = temp;
        for(int j=0;j<i;j++)
            res[j].pos=j;
        n=i-1;
    }
    void fun()
    {
        sort(p,p+n,cmp);
        int num;
        int total=100;
        if(n/2.0-n/2>0)
            num=n/2+1;
        else
            num=n/2;
        for(int i=0;i<num;i++)
        {
            res[p[i].pos].goal+=p[i].goal+1;
            total-=res[p[i].pos].goal;
        }
        n++;
        res[n-1].goal=total;
    }
    void reverse()
    {
        for(int i=0;i<n;i++)
            res[i].pos = n-res[i].pos-1;
    }
    void show()
    {
        sort(res,res+n,cmp2);
        cout<<"第一个海盗分金币的方案应为:"<<endl;
        for(int i=0;i<n;i++)
            cout<<res[i].goal<<" ";
        cout<<endl;
    }
};

void dfs(int n,heap& h)
{
    if(n==3)
    {
        h.p = new node[3];
        h.res = new node[3];
        h.p[0].goal=h.res[0].goal=0;
        h.p[1].goal=h.res[1].goal=0;
        h.p[2].goal=h.res[2].goal=100;
        for(int i =0;i<3;i++)
            h.p[i].pos=h.res[i].pos=i;
        h.n=3;
        return;
    }
    dfs(n-1,h);
    h.copy();
    h.rebuild(n);
    h.fun();
}

int main()
{
    int n;
    cout<<"输入海盗个数:";
    cin>>n;
    if(n==1)
    {
        cout<<"第一个海盗分金币的方案应为:"<<endl;
        cout<<"100"<<endl;
        return 0;
    }
    if(n==2)
    {
        cout<<"第一个海盗分金币的方案应为:"<<endl;
        cout<<"0 100"<<endl;
        return 0;
    }
    heap h;
    dfs(n,h);
    h.reverse();
    h.show();
    return 0;
}
时间: 2024-10-10 12:39:07

海盗分金的相关文章

海盗分金问题(博弈)

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

海盗分金的故事

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

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 a

海盗分金的问题

海盗分金好像是个博弈论的老问题了. 本科的时候听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块金子,并准备瓜分这些战利品.按照古老流传下来的分金法则,由最厉害的一名海盗提出一个分金方案,假如有不小于一半的海盗(包括自己)支持这个方案,则按这个方案分,否则把这个海盗扔进海里,重复由下一个厉害的海盗提出方案. 大家都知道,所有海盗都是贪婪的,虽然他们都乐于看到自己的同伴被扔进海里,但是他们还是希望在保命的前提下分的最多的金子,现在已经按海盗的厉害程

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

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

海盗分金问题

1. 有5个海盗,按照等级从5到1排列.最大的海盗有权提议他们如何分享100枚金币.但其他人要对此表决,如果多数(所有人中的多数)反对,那他就会被杀死.他应该提出怎样的方案,既让自己拿到尽可能多的金币又不会被杀死? 分配方案是98,0,1,0,1 5级海盗会不会被杀死,取决于5级海盗死后其他海盗是否会获得更多的利益.如果可以获得更多的利益,则肯定会反对,如果会获得更少的利益,则肯定会支持,如果利益没有变化,则反对或支持都可以. 如果5级海盗死了,则有4级海盗分配,4级海盗面临同样的问题,需要看自