PTA 海盗分赃

P 个海盗偷了 D 颗钻石后来到公海分赃,一致同意如下分赃策略:

首先,P 个海盗通过抽签决定 1 - P 的序号。然后由第 1 号海盗提出一个分配方案(方案应给出每个海盗分得的具体数量),如果能够得到包括 1 号在内的绝对多数(即大于半数)同意,则按照该分配方案执行,否则 1 号将被投入大海喂鲨鱼;而后依次类似地由第 2 号、第 3 号等等海盗提出方案,直到能够获得绝对多数同意的方案出现为止,或者只剩下最后一位海盗,其独占所有钻石。请编写一个程序,给出第 1 号海盗的钻石分配方案中自己分得的钻石数量。

附带的三个假定:

  • “聪明”与“贪婪”假定:每个海盗总能够以本人利益最大化作为行为准则;
  • “人性化”假定:在能够取得尽量多钻石的情况下,海盗不会故意致同伙于死地;
  • “无偏见”假定:海盗之间没有个人恩怨,分给其他海盗钻石的次序以小序号优先为原则。

输入格式:

输入在一行中给出 2 个正整数 D 和 P(3PD100)。

输出格式:

输出第 1 号海盗的钻石分配方案中自己分得的钻石数量。

输入样例:

10 7

输出样例:

6
这个题很有意思,之前这类题我也在博弈论的书上看到过,第一次写关于这个问题的算法,也是很新奇。
如果写在纸上,就不难发现他们的规律 让我们来写一下

(1)两个人 
1 海盗无论自己得到多少, 2肯定不同意,因为没有超过半数,所以只有 1 把所有的财产给 2 ,才能活命。
所以分配的结果为 : 0,D
(2)三个人
1 为了拉选票,肯定要笼络那些没有金币的人,那么金额为0就是首选的笼络人才, 而上面我们能看到 此刻的 2 金额为 0,其次打击财产最多的人(因为你无论给他多少(自身盈利的情况下)他都不会满足,所以不用考虑他的分配),所以 3 金额变成 0
所以分配的结果为 :D-1,1,0

(3)四个人
同样适用(2)的理论 那么此刻的 2 金额一定为 0 ,最后的人即 4 为拉拢对象,但是这样还不会超过半数,那么 3 就会比上次的多分配一枚金币
所以分配的结果为 :D-3,0,2,1

(4)五个人 (超过一大半也就是有 3个人支持)
同上面的理论,拉选票就从金额最小的人(0个金币)开始,如果不够,则考虑1个金币的人,如果人数够了,那么剩余人将分不到金币(自身利益最大化)
所以分配的结果为 :D-3,0,1,0,2

慢慢慢慢大家就会发现 海盗的人数超过三个人的时候就会出现规律
(5)六个人 分配的结果:D-4,0,1,2,1,0
(6)七个人 分配的结果:D-4,0,1,2,0,0,1
(7)八个人 分配的结果:D-5,0,1,2,0,1,1,0
(8)九个人 分配的结果:D-5,0,1,2,0,1,0,0,1
(9)十个人 分配的结果:D-6,0,1,2,0,1,0,1,1,0

发现规律了吗?
没错每次只需要给上一次金币数为0的家伙一枚金币,再给其中一个上一次得到一枚金币的家伙两枚金币,第一个海盗选票就超过一大半了!

那么转化为数学规律 当人数超过三个人的时候 第一个海盗得到的金币为: D - (P / 2 + 1)

代码如下:

#include<iostream>
using namespace std;
int main()
{
 int D, P;
 cin >> D >> P;
 if (P == 3)
  cout << D-1 << endl;
 else
  cout << D - (P / 2 + 1) << endl;
 return 0;
}
很短 不是吗 其实规律找到了 答案真的很简单!

猜你喜欢

转载自blog.csdn.net/tobealistenner/article/details/79896856
PTA