NYOJ 364 & HDU 1052 田忌赛马(贪心)

题目链接:Click here~~

好厉害的题,难度为1,纠结1天。在搜完无数大客后,终于有些略懂了。是用贪心做的, 这也应该是公认的解法吧。

题意:

田忌和齐王各有N匹马,判断怎样比赛,使田忌净胜场数最多。


我感觉这题的精髓就是,不管怎么比赛,都要让田忌的马发挥最大价值。

当然,马的第一要务是用来赢得比赛,而且要最大效益的赢,也就是要赢对方仅次于自己的马。

当他不能完成这个任务的时候就要去输,并拉对方最快的马下水,给自己后面的队友创造更大的胜利机会。


解题思路:

1.若田忌最慢的马可以战胜齐王最慢的马,那么就让它战胜那匹慢马,胜利场次加1。(田忌最慢马 > 齐王最慢马)

2.若田忌最慢的马不能战胜齐王最慢的马,那么它更加不能战胜其他的马,那就让它输,而且输给齐王最快马,失败场次加1。(田忌最慢马 < 齐王最快马)

3.若田忌最慢的马与齐王最慢的马速度相等。此时,不能简单地认为与它打成平手就是最好情况,相反,打平是下下策,为什么呢?

因为自己后面的队友很有可能战胜此时对方的这匹慢马,所以就算自己输一场,队友也能帮忙赢回一场,而胜一场,输一场的收益和打平一场的收益是一样的,而且自己输的时候可以拉对方最快的马下水,给己方最快的马创造更大的胜利机会(因为它失去了一个强劲的对手),也就是说己方最快的马很可能因为自己的牺牲再胜利一场,从这个角度看,还是自己故意输掉比较好。


但是,还有一点需要注意,当自己放水前,如果己方最快的马原本就比对方最快的马快,然后还输给对方最快的马,那么己方最快的马的才华就浪费了,为什么?

很简单,它原本就能赢,需要你放水么?- -!换句话说,这种情况下,自己的牺牲没有一点价值。

所以,在放水时,一定要保证己方最快马不快于对方最快马。满足此条件后,让己方最慢马与对方最快马去比赛(有可能平局),这样,田忌的马就得到了充分的利用。

#include <stdio.h>
#include <algorithm>
using namespace std;
int T[1002],K[1002],n,win,lose;
void read()
{
    for(int i=0;i<n;i++)
        scanf("%d",&T[i]);
    for(int i=0;i<n;i++)
        scanf("%d",&K[i]);
    sort(T,T+n);
    sort(K,K+n);
}
void race()
{
    win = lose =0;
    int t_slow=0,t_fast=n-1;
    int k_slow=0,k_fast=n-1;
    while(t_slow <= t_fast)
    {
        if(T[t_slow] > K[k_slow])        //情况1
        {
            win++;
            t_slow++;
            k_slow++;
        }
        else if(T[t_slow] < K[k_slow])   //情况2
        {
            lose++;
            t_slow++;
            k_fast--;
        }
        else                             //情况3
        {
            if(T[t_fast] > K[k_fast])    //先别放水,让哥比完这场
            {
                win++;
                t_fast--;
                k_fast--;
            }
            else                         //1、2、3、放
            {
                if(T[t_slow] < K[k_fast])//哥不一定会输哦~~~
                    lose++;
                t_slow++;
                k_fast--;
            }
        }
    }
}
int main()
{
    //freopen("1","r",stdin);
    //freopen("2","w",stdout);
    while(scanf("%d",&n),n)
    {
        read();
        race();
        printf("%d\n",200*(win-lose));
    }
    return 0;
}


  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值