浙大PAT 2-10. 海盗分赃 (解题思路)

2-10. 海盗分赃

时间限制
400 ms
内存限制
32000 kB
代码长度限制
8000 B
判题程序
Standard

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

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

附带的三个假定:

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

输入格式说明:

输入2个正整数D和P(3<=P<=D<=100)。

输出格式说明:

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

样例输入与输出:

序号输入输出
1
10 7
6
2
3 3
2
3
100 3
99
4
100 100
49

//大家可能看过经典的海盗分账问题,这题有点区别,因为他给了一些限制,看题目给的第三个案例,当输入为100 3时,输出为99. 可以想到的分配方式为99 1 0。我们理一下思路。如果倒数第四个人想获得最多的钻石而且获得半数以为上的票,他就应该给倒数第一和倒数第二个人2和1个钻石,因为倒数第三个人不管怎么样都会投出反对票,所以不用给他钻石,因为只要倒数第一和倒数第二人投他就行了,所以分配结果为97 0 2 1。依次类推,倒数第五个人也想到这点 ,所以他不会给倒数第四个人钻石,而他只要给倒数第三个人一个钻石就可以了,现在还差一票,所以只要给倒数第一个人2颗钻石他就会乖乖的投你一票,而倒数第二个就不要给他钻石了,得到分配方式97 0 1 0 2.再依次类推,你会发现,在倒数第n人分配的时候,倒数第n-1个人一定会反对,所以倒数第n个人想要获得半数以上的票,就要把希望寄托在倒数第1~(n-2)这 n-2个人身上。所以只要给其中(n-2)/2+1个人的钻石数比第n-1个人给他们的要多一个,他们就会支持你。所以算法可以对后面的n-2个人进行排序,并挑取钻石数最少的(n-2)/2+1个人,多给他们一个钻石,而对于其他的人,直接不给钻石。。这样就ok了。


#include <iostream>
#include <deque>
#include <algorithm>
using namespace std;

deque<int> de;

int main()
{
	int D, P;
	cin>>D>>P;
	de.push_back(0);
	de.push_back(1);
	de.push_back(D-1);
	int i;
	for(i = 3; i < P; ++i)
	{
		sort(de.begin(), de.end());
		int j, sum = 0;
		for (j = 0; j < de.size(); ++j)
		{
			if(j < (de.size()-1)/2+1)
			{
				de[j] ++;
				sum += de[j];
			}
			else
				de[j] = 0;
		}
		de.push_back(D-sum);
	}
	cout<<de[P-1]<<endl;
	return 0;
}




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值