您的位置:首页 > 其它

贪心算法 Problem C 1002 田忌赛马

2016-03-19 21:29 197 查看


Problem C Problem ID:1002

简单题意:田忌与齐王赛马,每人的有相同数量的马匹,但每匹马上场且仅上场一次,每一场输掉,输的人给赢的人200两银子。给出两人的所有马匹的速度,求田忌所能获得的最多的银子。

解题思路形成过程:1.当田忌最慢的马比齐王最慢的马慢时,将田忌的这匹马与齐王最快的马进行比试(输200两);

2.当田忌最慢的马比齐王最慢的马快时,将这两匹马进行比试(赢200两);

3.(重点)当田忌最慢的马与齐王最慢的马速度相同时,再分成两种情况进行考虑:

①若田忌最快的马比齐王最快的马慢或者速度相同时,用田忌最慢的马与齐王最快的马进行比试。因为此时虽然会输掉,但是田忌最快的马将很有可能赢得将来的比赛,且后面田忌还很有可能可以赢得此时齐王最慢的马,这样收益最大。(注意:田忌最慢的马不一定比齐王最快的马慢!比如测试样例:2\n 20 20 \n 20 20)

②若田忌最快的马比齐王最快的马快时,先将这两匹最快的马进行比试,赢得200两,再进入第三步(3.)的循环判断。

感想:要顾全大局,仔细分析思考如何才能获得最大收益,一时的平局甚至败局可能会让整体的收益更高。

代码:


#include<iostream>
#include<stdio.h>
#include<set>
using namespace std;
int main()
{
int n;
multiset <int> s1,s2;
multiset <int>::iterator s1i,s2i,s1ii,s2ii;
while(scanf("%d",&n)!=EOF&&n){
int n1=n,n2=n,n3=n;
int total=0;
while(n1--){
int temp;
cin>>temp;
s1.insert(temp);
}
while(n2--){
int temp;
cin>>temp;
s2.insert(temp);             //insert会改变相应的迭代器所指向的位置。
}
s1i=s1.begin();
s2i=s2.begin();
for(int i=0;i<n3;++i,s1i=s1.begin(),s2i=s2.begin())
{
if((*s1i)<(*s2i)){           //当田忌最慢的马比齐王最慢的马慢时,将田忌的这匹马与齐王最快的马进行比试。
total-=200;
s1.erase(s1i);
s2i=s2.end();
s2.erase(--s2i);
}
else if((*s1i)>(*s2i)){     //当田忌最慢的马比齐王最慢的马快时,将这两匹马进行比试。
total+=200;
s1.erase(s1i);
s2.erase(s2i);
}
else if((*s1i)==(*s2i)){    //当田忌最慢的马与齐王最慢的马速度相同时,再分成两种情况进行考虑:
s1ii=s1.end();
--s1ii;
s2ii=s2.end();
--s2ii;
if((*s1ii)>(*s2ii)){    //若田忌最快的马比齐王最快的马快时,先将这两匹最快的马进行比试。
total+=200;
s1.erase(s1ii);
s2.erase(s2ii);
}
else{                   //若田忌最快的马比齐王最快的马慢或者速度相同时,用田忌最慢的马与齐王最快的马进行比试。
if((*s1i)<(*s2ii))
total-=200;
s1.erase(s1i);
s2i=s2.end();
s2.erase(--s2i);    //获取/删除 最后一个位置的元素:利用end()和调整迭代器。
}
}
}
cout<<total<<endl;
s1.clear();
s2.clear();
}
return 0;
}

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: