算法竞赛学习笔记—田忌赛马(贪心法)

题目描述:田忌和齐王赛马,胜一场可获得200金,负一场损失200金,平局无得无失。现在给出马的数量,田忌的每匹马的速度和齐王每匹马的速度,求出田忌最多可以赢得多少金。

输入输出:包含多组数据,每组数据的第一行为一个正整数n(n<=1000),表示每一方有多少匹马,第二行为n个整数,表示田忌每匹马的速度,第三行n个整数表示齐王每匹马的速度。当n为0时,表示输入数据结束。每组样例输出一行,给出田忌可以赢得的具体金数。

输入样例:

3

92 83 71

95 87 74

2

20 20

20 20

2

20 19

22 18

0

输出样例:

200

0

0

题目分析:

策略是充分利用每一匹马的战斗力,若己方的最好马优于对方的最好马,则使己方的最好马战胜对方的最好马;若己方的最好马劣于对方的最好马,则必定要输一次,用己方最劣的一匹马消耗对方的最好马,从而使己方的最好马可以对战对方下一个等级的马,增大赢的概率。当双方的最好马实力相当时,为了尽可能多赢,检查双方最劣马的实力,若己方最劣马强于对方,则先用己方最劣马战胜对方最劣马,保证赢一局,若己方最劣马弱于对方,则该匹马注定要输,用其消耗对方最高战斗力。若双方最劣马实力相当,仍用己方最劣马消耗对方最好马,当只看最优和最劣两组数据时,这样最坏的结果是平局,然而可以增大中间数据赢的概率(因为己方的最优马得以对阵对方下一等级的马,且对方下一等级的马战斗力一定小于等于它)。

代码实现:

#include<iostream>
#include<vector>
#include<algorithm>
using namespace std;
int main()
{
vector<int> tian,king;
int n;
int i,j;
int sum;
int tworst,kworst,tbest,kbest;
while(cin>>n&&n)
{
tian.resize(n);
king.resize(n);
for(i=0;i<n;i++)
{
cin>>tian[i];
}
for(i=0;i<n;i++)
{
cin>>king[i];
}
   sort(tian.begin(),tian.end());
   sort(king.begin(),king.end());
   //for(i=0;i<n;i++)
   //{
   // cout<<tian[i]<<” “<<king[i]<<endl;
//}
   tworst=0;kworst=0;
   tbest=n-1;kbest=n-1;
   sum=0;
   while(tworst<=tbest)
   {
    if(tian[tbest]>king[kbest])
    {
    sum+=200;
    tbest–;
    kbest–;
}
else if(tian[tbest]<king[kbest])
{
sum-=200;
kbest–;
tworst++;
}
else if(tian[tbest]==king[kbest]&&tian[tworst]>king[kworst])
{
sum+=200;
tworst++;
kworst++;
}
else if(tian[tbest]==king[kbest]&&tian[tworst]<=king[kworst])
{
 if(tian[tworst]<king[kbest])
   sum-=200;
 tworst++;
 kbest–;
   }
   }
   cout<<sum<<endl;
   tian.clear();
   king.clear();
}
    return 0;
 } 

    原文作者:贪心算法
    原文地址: https://blog.csdn.net/fania111/article/details/78165446
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞