hdu 1052 Tian Ji -- The Horse Racing(经典贪心)

前言:非常经典的题,由于我贪心策略想的简单了点,漏了些情况,也根本行不通,看了好几个大牛思路缜密的代码,果然我还是太弱了。
题意:田忌和齐王各有N匹马,数字代表能力,判断怎样比赛,使田忌净胜场数最多。(历史上情景一样)
开始我思路是,将两人马按从大到小排序,实现让每一个田忌的马赢得最有价值,就是让田忌的马和比它能力弱且差值最小的马比,平就平呗(恰恰是我漏想的情况),当然我这种策略有着明显的错误。
正确解法:
一、当田忌最快的马比国王最快的马快时,用田忌最快的马赢国王最快的马。(赢的最有价值)
二、当田忌最快的马比国王最快的马慢时,用田忌最慢的马输给国王最快的马。(输的最有价值)
三、当田忌最快的马跟国王最快的马一样快时,如果田忌最慢的马比国王最慢的马还要快,直接比。如果不是,就让田忌最慢的马与国王最快的马比。(解释:这里有一种情况 是田忌最慢的马和国王最慢的马平时,不如让田忌最慢的马和国王最快的马比,两种情况结果都是输一次,但是这里牺牲田忌最慢的马区消耗 国王最快的马,更有价值。)

#include<cstdio>
#include<algorithm>
using namespace std;
int t[1010],k[1010];
bool cmp(int a,int b)
{
    return a>b;
}
int main()
{
    int n;
    while(scanf("%d",&n)&&n)
    {
        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,cmp);sort(k,k+n,cmp);
        int t_fast=0,t_slow=n-1,k_fast=0,k_slow=n-1,win=0,lose=0;
        while(t_fast<=t_slow)
        {
            if(t[t_fast]>k[k_fast])
            {
                win++;
                t_fast++;
                k_fast++;
            }
            else if(t[t_fast]<k[k_fast])
            {
                lose++;
                k_fast++;
                t_slow--;
            }
            else
            {
                if(t[t_slow]>k[k_slow])
                {
                    win++;
                    t_slow--;
                    k_slow--;
                }
                else
                {
                    if(t[t_slow]<k[k_fast])
                        lose++;
                    t_slow--;
                    k_fast++;
                }
            }
        }
        printf("%d\n",(win-lose)*200);
    }
}

根据这种贪心的策略:赢与对方中自己最接近的,输给对方最大的。
同理,还可以
(转载别人博客)
1.若田忌最慢的马可以战胜齐王最慢的马,那么就让它战胜那匹慢马,胜利场次加1。(田忌最慢马 > 齐王最慢马)
2.若田忌最慢的马不能战胜齐王最慢的马,那么它更加不能战胜其他的马,那就让它输,而且输给齐王最快马,失败场次加1。(田忌最慢马 < 齐王最快马)
3.若田忌最慢的马与齐王最慢的马速度相等。此时,不能简单地认为与它打成平手就是最好情况,相反,打平是下下策,为什么呢?
因为自己后面的队友很有可能战胜此时对方的这匹慢马,所以就算自己输一场,队友也能帮忙赢回一场,而胜一场,输一场的收益和打平一场的收益是一样的,而且自己输的时候可以拉对方最快的马下水,给己方最快的马创造更大的胜利机会(因为它失去了一个强劲的对手),也就是说己方最快的马很可能因为自己的牺牲再胜利一场,从这个角度看,还是自己故意输掉比较好。
但是,还有一点需要注意,当自己放水前,如果己方最快的马原本就比对方最快的马快,然后还输给对方最快的马,那么己方最快的马的才华就浪费了,为什么?
很简单,它原本就能赢,需要你放水么?- -!换句话说,这种情况下,自己的牺牲没有一点价值。
所以,在放水时,一定要保证己方最快马不快于对方最快马。满足此条件后,让己方最慢马与对方最快马去比赛(有可能平局),这样,田忌的马就得到了充分的利用。

#include<cstdio>
#include<algorithm>
using namespace std;
int a[1010],b[1010];
int main()
{
    int n;
    while(scanf("%d",&n)&&n)
    {
        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);
        int t_fast=n-1,t_slow=0,k_fast=n-1,k_slow=0,win=0,lose=0;
        while(t_slow<=t_fast)
        {
            if(a[t_slow]>b[k_slow])
            {
                win++;
                t_slow++;
                k_slow++;
            }
            else if(a[t_slow]<b[k_slow])
            {
                lose++;
                t_slow++;
                k_fast--;
            }
            else
            {
                if(a[t_fast]>b[k_fast])
                {
                    win++;
                    k_fast--;
                    t_fast--;
                }
                else
                {
                    if(a[t_slow]<b[k_fast])
                        lose++;
                    t_slow++;
                    k_fast--;
                }
            }
        }
        printf("%d\n",(win-lose)*200);
    }
}

你可能感兴趣的:(hdu 1052 Tian Ji -- The Horse Racing(经典贪心))