重提强盗分宝石问题

oyd 2003-04-16 07:06:51
问题:
有5个强盗A,B,C,D,E,得到100个金币,决定瓜分掉,分法怪异:
首先A提出分法,B,C,D,E表决,如果不过半数同意,就砍掉A的头(2:2也砍掉)
然后由B来分,C,D,E表决,如果不过半数同意,就砍掉B的头
依次类推,如果假设强盗都足够聪明,在不被砍掉头的同时获得最多的金币。

许多人的答案似乎都是
97,0,1,1,1
有代表性的理由如下:
每个强盗都很聪明,所以e虽然占有了有利位置,他也该想到c d为了活命一定支持b,既然c d 无论如何都要支持b,也不可能从b 手中拿到任何好处,所以a死了,cde都拿不到钱,为了拿最多的钱,只要a给一点点好处就会受到cde 的支持.所以最后最后结果一定是
a:97
b:0
c:1
d:1
e:1

可是你们忽略了一个问题:轮d分配时,他必死,所以他会同意c的任何方案,以避免c死后他也死的结果。这样c就可以提出100,0,0的方案来。
口说无凭,人的思维难免会有疏漏,用程序来作答吧。
程序运行的结果:5个强盗时最佳方案为97,0,1,0,2

/*程序:robber.cpp,vc++6.0下编译通过
* 因为100颗宝石用时间比较长,所以减为10颗
* vote函数用于模拟强盗投票,displaymethod函数用于显示方案
* 基于运算速度考虑,中间结果的输出被注释掉 。
*
*/


#include <iostream>
typedef struct _method
{
int stone[100];//存每个强盗分到的宝石数
int robbernum;//存强盗的数目
}Method;
Method *pBestMethod[100];//全局变量,用于存入已经找到的最佳方案
const int MAXSTONENUM=10;//待分配的宝石数
class Robber
{
public:
Robber(int num)
:m_num(num)
{
m_goodmethod.robbernum=0;
m_goodmethod.stone[num]=0;
}
bool vote(Method method);//对方案投票
int profit(Method method);
Method GetBestMethod();
void DisplayMethod();
private:
void Get(int m,int n);//用于列举所有方案的递归函数
void judge();//判断和比较方案的过程
const int m_num;//强盗的编号
Method m_method;//用于临时存储方案
Method m_goodmethod;//存储好方案
};


bool Robber::vote(Method method)
{
Method nextMethod;
do
{
Robber nextRobber(--method.robbernum);//下一个制定方案者
nextMethod=nextRobber.GetBestMethod();
}
while(nextMethod.stone[nextMethod.robbernum]==-1);
if(this->profit(method)>this->profit(nextMethod))
{
//std::cout<<"r"<<m_num<<":O ";//O表示同意
return true;
}
//std::cout<<"r"<<m_num<<":X ";//X表示否决
return false;
}
int Robber::profit(Method method)
{
return method.stone[m_num];
}
Method Robber::GetBestMethod()
{
Method method;
if(m_num==1)
{
method.stone[1]=MAXSTONENUM;
method.robbernum=m_num;
return method;
}
if(pBestMethod[m_num]!=NULL)return *pBestMethod[m_num];//已有方案
Get(MAXSTONENUM,m_num);
if(m_goodmethod.robbernum==0)//找不到可以通过投票的方案
{
std::cout<<"I am dead";
m_method.robbernum=m_num;
method=m_method;
method.stone[m_num]=-1;
}
else method=m_goodmethod;
pBestMethod[m_num]=new Method;
*pBestMethod[m_num]=method;
return method;

}
void Robber::Get(int m,int n)//把m个数分到n个人
{
if(m==0)
{
for(int i=1;i<=n;i++)
{
m_method.stone[i]=0;
}
m_method.robbernum=m_num;
judge();
return;
}

if(n==1)
{
m_method.stone[n]=m;
m_method.robbernum=m_num;
judge();
return;
}
for(int i=m;i>=0;i--)
{
m_method.stone[n]=i;
Get(m-i,n-1);
}


}
void Robber::judge()
{
int votes=1;
//DisplayMethod();
for(int i=m_num-1;i>=1;i--)
{
Robber robber(i);//假想其他强盗的投票
if(robber.vote(m_method))votes++;

}
if ((2*votes>m_num)&&(profit(m_method)>=profit(m_goodmethod)))
{//半数以上通过,且不比原先的方案差。
m_goodmethod=m_method;
}
}
void Robber::DisplayMethod()
{
std::cout<<std::endl;
for (int i=m_num;i>0;i--)
{
std::cout<<m_method.stone[i]<<" ";
}
std::cout<<"\t";
}
void main()
{
int num;
while(true)
{
std::cout<<"Input Robber number"<<std::endl;
std::cin>>num;

Robber theRobber(num);
Method method;
method=theRobber.GetBestMethod();
std::cout<<std::endl;
for(int i=method.robbernum;i>=1;i--)
std::cout<<method.stone[i]<<" ";
for(i=num-1;i>=1;i--)
{
Robber robber(i);
robber.vote(method);
}
}
}

...全文
125 4 打赏 收藏 转发到动态 举报
写回复
用AI写文章
4 条回复
切换为时间正序
请发表友善的回复…
发表回复
ninesong 2003-04-22
  • 打赏
  • 举报
回复
提出解决方案参与投票的解决是98 。。。。。
提出解决方案不参与投票的解决是97,0,1,0,2
gumbour 2003-04-21
  • 打赏
  • 举报
回复
但还有一个前提是每个强盗都珍惜自己的生命
我记得是自己利益不受影响的时候,强盗认为死的人越多越好
如果前面的人死掉,自己的生命会受到影响,他会希望前面的人死掉吗?
DavidBone 2003-04-18
  • 打赏
  • 举报
回复
up
killerqueen1208 2003-04-16
  • 打赏
  • 举报
回复
首先,从进行到只有两名海盗时开始分析,几只剩下4和5号海盗,由于只有两人,故无论4怎样分,4都比死,5得100枚钻石。
现在加上3号海盗,由于在上一种情况中,5能得到所有钻石,故5希望3死,只剩下4和5,故3无论怎样分5都不会同意,5必投反对票,而4不希望自己死,故给4号海盗0枚钻石就会同意,而3号海盗本身比同意自己的分法,故分法为:100,0,0。这样可以得到4的同意票和5的反对票。
现在再加上2号海盗,同上,2号海盗无论怎样分3号都不会同意,故2要得到4和5的两枚赞同票他才能不死,又因为海盗认为获得的钻石不变,死的人越多越好,故应给4号和5号各一枚钻石,故分法为:98,0,1,1。
再加上1号海盗,2号必不会同意,故他要在3,4,5号海盗中得到2票,这样的话,它要分给3号海盗一枚,得到一票,而可以分给4和5两人中一人0枚,另一人2枚得到另一票,故分法为:97,0,1,0,2或97,0,1,2,0

我这样分的原因是我找到的原题还有一个条件为:在分到钻石同样多的情况下,强盗认为斯的人越多越好!
内容概要:本文研究了一种应用于太阳能发电系统的多级逆变器,旨在通过采用正弦脉宽调制(SPWM)技术有效降低输出电压的总谐波失真(THD),从而提升电能质量。研究基于Simulink平台构建了完整的仿真模型,系统地实现了SPWM信号生成、驱动逻辑控制以及多电平输出波形合成等关键环节,验证了该多级逆变器在不同运行工况下具备优异的动态响应能力和稳定性。仿真结果表明,所设计的逆变器能够输出接近理想正弦波的电压波形,显著抑制高次谐波,满足可再生能源并网对电能质量的严苛要求,体现出多级逆变拓扑在光伏发电系统中的技术先进性与工程应用价值。; 适合人群:电气工程、自动化、新能源科学与工程及相关专业的本科生、研究生,以及从事光伏逆变器设计、电力电子变换技术和可再生能源并网系统研发的工程技术人员。; 使用场景及目标:①深入理解多级逆变器的工作原理及其在太阳能发电系统中的关键作用;②掌握SPWM调制技术的理论基础与实现方法,并析其对改善THD的核心机制;③借助Simulink仿真平台开展电力电子电路的建模、参数调试与性能评估,服务于课程设计、毕业设计、科研课题或实际工程项目开发。; 阅读建议:建议读者结合提供的Simulink仿真模型进行同步操作与验证,细致调整调制比、载波频率等关键参数,观察其对输出波形和THD指标的影响,以深化对系统动态特性的理解,并尝试优化控制策略以进一步提升系统性能。
VCF 生成器 Lite v6.0.0:批量导入与功能拓展 VCF 生成器 Lite v6.0.0 正式版已发布,此次更新带来了批量导入手机通讯录这一重要功能,极大地方便了用户整理和管理联系人信息。同时,新增了多项功能,如翻译所有 CLI 内容,让不同语言背景的用户都能更好地使用;verbose 模式新增更多日志信息,有助于用户更详细地了解操作过程。 此外,还添加了多地区号码格式支持,包括中国港澳台地区电话号码格式,满足了不同地区用户的需求。当未捕获异常时,系统会自动保存错误日志,并引导用户反馈给开发者,这体现了产品团队对用户体验 的重视,有助于及时发现和解决问题。 修复痛点:引号清理与进度条显示问题 在修复方面,此次更新解决了引号清理功能在包含换行符时的错误行为,以及自 `v4.3.0` 版本以来的进度条显示问题。这些问题虽然看似微小,但却影响了用户的使用体验,修复后能让用户更加顺畅地使用 VCF 生成器 Lite。 代码与文档重构:提升可维护性与易用性 在变更方面,将翻译框架迁移到 gettext,提升了 `LANGUAGE` 环境变量 优先级,方便用户根据自己的语言偏好进行设置。在 AI 的指导下重构项目,使得各层次职责更加清晰,代码更加模块化,可维护性更高,这为产品的后续发展奠定了良好的基础。 同时,按 Diataxis 框架重构用户文档,按开发生命周期 重组开发者文档,让用户和开发者都能更方便地获取所需信息,提高了产品的易用性。 编辑观点:VCF 生成器 Lite v6.0.0 的更新在功能、修复和代码文档方面都有显著提升,满足了用户的实际需求,增强了产品的竞争力,未来有望在市场上取得更好的成绩。

33,025

社区成员

发帖
与我相关
我的任务
社区描述
数据结构与算法相关内容讨论专区
社区管理员
  • 数据结构与算法社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧