#include <iostream>
#include <unordered_map>
#include <map>

// 假定:每个海盗都是一样的聪明,没有谁比谁笨,都很理智可以 做出理性的决策,那么1号如何决策才能使自己的收益最大且当然不会被扔进大海里喂鲨鱼?

//  答案分析: 1号海盗分给3号1枚金币,4号或5号2枚金币,自己则独得97枚金币,即分配方案为(97,0,1,2,0)或(97,0,1,0,2)。

// 现来看如下各人的理性分析:

// 5号海盗:因为他是最安全的,没有被扔下大海的风险,因此他的策略也最为简单,即最好前面的人全都死光光,那么他就可以独得这100枚金币了。
// 4号海盗:他的生存机会完全取决于前面还有人存活着,因为如果1号到3号的海盗全都喂了鲨鱼,那么在只剩4号与5号的情况下,不管4号提出怎样的分配方案,5号一定都会投反对票来让4号去喂鲨鱼,以独吞全部的金币。哪怕4号为了保命而讨好5号,提出(0,100)这样的方案让5号独占金币,但是5号还有可能觉得留着4号有危险,而投票反对以让其喂鲨鱼。因此理性的4号是不应该冒这样的风险,把存活的希望寄托在5号的随机选择上的,他惟有支持3号才能绝对保证自身的性命。
// 3号海盗:他经过上述的逻辑推理之后,就会提出(100,0,0)这样的分配方案,因为他知道4号哪怕一无所获,也还是会无条件的支持他而投赞成票的,那么再加上自己的1票就可以使他稳获这100金币了。
// 2号海盗:也经过推理得知了3号的分配方案,那么他就会提出(98,0,1,1)的方案。因为这个方案相对于3号的分配方案,4号和5号至少可以获得1枚金币,理性的4号和5号自然会觉得此方案对他们来说更有利而支持2号,不希望2号出局而由3号来进行分配。这样,2号就可以屁颠屁颠的拿走98枚金币了。
// 1号海盗:经过一番推理之后也洞悉了2号的分配方案。他将采取的策略是放弃2号,而给3号1枚金币,同时给4号或5号2枚金币,即提出(97,0,1,2,0)或(97,0,1,0,2)的分配方案。由于1号的分配方案对于3号与4号或5号来说,相比2号的方案可以获得更多的利益,那么他们将会投票支持1号,再加上1号自身的1票,97枚金币就可轻松落入1号的腰包了。

void assgin(int p, int g)
{
    using namespace std;
    std::unordered_map<int, int> method_before{{1, 100}, {2, 0}, {3, 0}};
    int num = 3;
    
    while (++num <= p)
    {
        int flag = num / 2;
        std::multimap<int, int> method_after;
        cout << num << endl;
        for (auto iter = method_before.begin(); iter != method_before.end(); ++iter)
        {
            method_after.emplace(iter->second, iter->first);
            method_before[iter->first] = 0;
        }
        method_before.emplace(num, 0);
        for (auto iter = method_after.begin(); iter != method_after.end(); ++iter)
        {
            if (flag == 0)
                break;
            method_before[iter->second + 1] = iter->first + 1;
            --flag;
        }
        int sum = 0;
        for (auto iter = method_before.begin(); iter != method_before.end(); ++iter)
        {
            sum += iter->second;
        }
        method_before[1] = g - sum;
        for (auto iter = method_before.begin(); iter != method_before.end(); ++iter)
        {
            cout << iter->first << ":" << iter->second << " ";
        }
        cout << endl;
    }

    
}

int main(void)
{
    int personNum = 10;
    int goldNum = 100;
    assgin(personNum, goldNum);
    return 0;
}

运行结果

4
4:1 3:1 2:0 1:98
5
5:2 4:0 3:1 2:0 1:97
6
6:0 5:1 4:2 3:1 2:0 1:96
7
7:1 6:2 5:0 4:0 3:1 2:0 1:96
8
8:2 7:0 6:1 5:1 4:0 3:1 2:0 1:95
9
9:0 8:1 7:2 6:0 5:1 4:0 3:1 2:0 1:95
10
10:1 9:2 8:0 7:1 6:0 5:1 4:0 3:1 2:0 1:94
➜ CPP

 posted on 2022-04-03 03:32  缘初  阅读(350)  评论(0编辑  收藏  举报