HDU 1052Tian Ji -- The Horse Racing

很有意思的一道题,做完这道题你就会充分的了解田忌赛马的策略了,要考虑的情况还是挺多的,挺考验思维的严谨性的。。。
好,废话不多说,下面开始题目的分析。
这道题的核心思想是贪心,其贪心策略的精髓就在于让田忌的每一匹马都发挥到最大价值,即每一次做出的选择都要是最优的的策略(这个选择指的是当田忌的一匹马要在对手的阵营中选出一匹马作为对手时,要选择一个能将自己的价值发挥到最大的对手)。
那么对于这道题来说何为最优的策略呢?
对于田忌的马来说,如果目前可以赢得比赛(即可以找到比自己弱的对手),那么第一选择就是赢得比赛,而且要最大效益的赢,也就是要赢对方仅次于自己的马。
当它实在没有办法赢的时候(即找不到比自己弱的对手),要么打个平局,要么去输,而且要输给对方最快的马,最大限度的发挥自己的价值(反正都是输,还不如输给最快的,拖他们最牛逼的下水,给自己后面的队友创造更大的胜利机会。)

解题思路:
1.若田忌最慢的马可以战胜齐王最慢的马,那么就让它战胜那匹慢马,胜利场次加1。(田忌最慢马 > 齐王最慢马)
2.若田忌最慢的马不能战胜齐王最慢的马,那么它更加不能战胜其他的马,那就让它输,而且输给齐王最快马,失败场次加1。(田忌最慢马 < 齐王最快马)
3.若田忌最慢的马与齐王最慢的马速度相等。此时,不能简单地认为与它打成平手就是最好情况,相反,打平是下下策,为什么呢?
因为自己后面的队友很有可能战胜此时对方的这匹慢马,所以就算自己输一场,队友也能帮忙赢回一场,而胜一场,输一场的收益和打平一场的收益是一样的,而且自己输的时候可以拉对方最快的马下水,给己方最快的马创造更大的胜利机会(因为它失去了一个强劲的对手),也就是说己方最快的马很可能因为自己的牺牲再胜利一场,从这个角度看,还是自己故意输掉比较好。

但是,还有一点需要注意,当自己放水前,如果己方最快的马原本就比对方最快的马快,然后还输给对方最快的马,那么己方最快的马的才华就浪费了,为什么?
很简单,它原本就能赢,需要你放水么?- -!换句话说,这种情况下,自己的牺牲没有一点价值。
所以,在放水时,一定要保证己方最快马不快于对方最快马。满足此条件后,让己方最慢马与对方最快马去比赛(有可能平局),这样,田忌的马就得到了充分的利用。

下面贴代码:

#include <algorithm>
#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <ctime>
#include <ctype.h>
#include <iostream>
#include <map>
#include <queue>
#include <set>
#include <stack>
#include <string>
#include <vector>
#define eps 1e-8
#define INF 0x7fffffff
#define PI acos(-1.0)
#define seed 31//131,1313
#define MAXV 50010
typedef long long LL;
typedef unsigned long long ULL;
using namespace std;
int a[1005];
int b[1005];
int n;
int win,lose;
void Race()
{
    win=lose=0;
    int Tian_slow=0,Qi_slow=0;
    int Tian_fast=n-1,Qi_fast=n-1;
    while(Tian_slow<=Tian_fast){
        if(a[Tian_slow]>b[Qi_slw]){
            win++;
            Tian_slow++;
            Qi_slow++;
        }
        else if(a[Tian_slow]<b[Qi_slow]){
            lose++;
            Tian_slow++;
            Qi_fast--;
        }
        else if(a[Tian_slow]==b[Qi_slow]){
            if(a[Tian_fast]>b[Qi_fast]){
                win++;
                Tian_fast--;
                Qi_fast--;
            }
            else {
                if(a[Tian_slow]<b[Qi_fast])  lose++;
                Tian_slow++;
                Qi_fast--;
            }
        }
    }
}
int main()
{

    while(scanf("%d",&n)!=EOF)
    {
        if(n==0) break;
        for(int i=0; i<n; i++)
        {
            scanf("%d",&a[i]);
        }
        for(int i=0; i<n; i++)
        {
            scanf("%d",&b[i]);
        }
        sort(a,a+n);
        sort(b,b+n);
        Race();
        printf("%d\n",(win-lose)*200);
    }
    return 0;
}
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值