zoukankan      html  css  js  c++  java
  • 洛谷 P1650 田忌赛马题解

    原题目链接:https://www.luogu.com.cn/problem/P1650

    思路

    需要的是一个贪心算法,这个地方我们只要把贪心的时候把每种分支情况考虑清楚,就可以保证自己做的贪心都是正确的了。

    我们先对田忌的马按照速度从大到小排序,齐王的也是。因为田忌可以自由选择顺序,所以这个地方是正确的。

    接下来开始贪心

    我们的原则从速度快的马开始考虑,如果选择出来的那匹马能赢,就一定要赢,如果不赢,反正我赢不了,就拿烂的马恶心齐王。

    1: 如果在剩下的所有马里,如果田忌跑的最快的马,比齐王跑的最块的马还快,那么田忌自然需要让马出场,赢了这把。

    2: 如果在剩下的所有马里,如果田忌跑的最快的马,比齐王跑的最块的马要慢,那么这样田忌所有的马绝对没有可能会赢齐王最快的马了,反正都是输,所以这个时候我们只能用田忌最烂的马去把齐王最好的马抵掉。这样一来还能造成一个局面,就是田忌只损失了最烂的一匹马,但是剩余的马都是很优秀的,但是齐王却损失了最好的一匹马,虽然这把输了,但是日后赢回来的可能性是最大的。

    3: 如果在剩下的所有马里,如果田忌跑的最快的马,和齐王跑的最快的马一样快,这个时候我们我们考虑最慢的两匹马(为什么突然想到考虑这两匹马,这个我感觉是需要点脑洞的,我也不知道,可能是这样方便贪心吧,毕竟每次都要选择一匹马上场 XD)

    4: 如果田忌最慢的马比齐王最慢的马还要块,那么就赢了他,毕竟如果你不赢了,之后就没机会了。

    5: 如果田忌最慢的马比齐王最慢的马还要慢,啧啧啧,我看这面相,怕是没戏,所以这匹马直接去和齐王最快的马比。反正横竖赢不了。

    6: 最麻烦的一点来了,如果田忌这个时候最慢的马还是和齐王最慢的马一样快,那怎么处理呢?这个时候因为这匹马最多只是平局,那么还是只能和齐王最慢的马比较了

    按照这样我们就能至少让每把比赛都能有一个马上场,而且能确保
    上场的马要么能赢,要么对整体结果的损失最小

    代码

    #include <iostream>
    #include <algorithm>
    
    using std::cin;
    using std::cout;
    using std::endl;
    using std::sort;
    
    const int N = (int)2e3 + 5;
    
    int a[N]; // 田忌的数据
    int b[N]; // 齐王的数据
    
    bool cmp(int a, int b) 
    {
        return a > b;
    }
    
    int main()
    {
        int n;
        cin >> n;
        for (int i = 0; i < n; i++)
            cin >> a[i];
        sort(a, a + n, cmp);
        for (int i = 0; i < n; i++)
            cin >> b[i];
        sort(b, b + n, cmp);
    
        int s1 = 0, e1 = n - 1;
        int s2 = 0, e2 = n - 1;
    
        int money = 0;
        while (n > 0)
        {
            if (a[s1] > b[s2])
            {
                money += 200;
                s1++;
                s2++;
            }
            else if (a[s1] < b[s2])
            {
                money -= 200;
                e1--;
                s2++;
            }
            else
            {
                if (a[e1] > b[e2])
                {
                    money += 200;
                    e1--;
                    e2--;
                }
                else if (a[e1] < b[s2])
                {
                    money -= 200;
                    e1--;
                    s2++;
                }
                else 
                {
                    e1--;
                    e2--;
                }
            }
            n--;
        }
    
        cout << money << endl;
    
        return 0;
    }
    
  • 相关阅读:
    [Linux起步]常用命令
    Eclipse被SD杂志评为最佳开源工具
    [一点一滴学英语]20050921
    [一点一滴学英语]20050920
    [一点一滴学英语]20050919
    Longhorn (Vista) 推迟发布的背后
    最快速度找到内存泄漏
    重载(overload)、覆盖(override)、隐藏(hide) 详解
    HTTP请求和响应格式
    Skia之四——SkGradientShader篇
  • 原文地址:https://www.cnblogs.com/Node-Sans-Blog/p/15221755.html
Copyright © 2011-2022 走看看