HDU - 1052 田忌赛马 贪心

版权声明:博主的博客不值钱随便转载但要注明出处 https://blog.csdn.net/easylovecsdn/article/details/85215083

这道题,乍看很简单(其实也不算难题),WA掉......换了思路,还是WA......,看了下题解思路(感谢博主https://blog.csdn.net/smilecarol/article/details/47066613 ),ORZ!

用贪心法解决此问题

1.当田忌最慢的马比齐王最慢的马快,赢一场先
2.当田忌最慢的马比齐王最慢的马慢,和齐王最快的马比,输一场
3.当田忌最快的马比齐王最快的马快时,赢一场先。
4.当田忌最快的马比齐王最快的马慢时,拿最慢的马和齐王最快的马比,输一场。
5.当田忌最快的马和齐王最快的马相等时,拿最慢的马来和齐王最快的马比.

田忌赛马贪心的正确性证明。

先说简单状况下的证明:
1.当田忌最慢的马比齐王最慢的马快,赢一场先。因为始终要赢齐王最慢的马,不如用最没用的马来赢它。
2.当田忌最慢的马比齐王最慢的马慢,和齐王最快的马比,输一场。因为田忌最慢的马始终要输的,不如用它来消耗齐王最有用的马。
3.当田忌最慢的和齐王最慢的马慢相等时,分4和5讨论。
4.当田忌最快的马比齐王最快的马快时,赢一场先。因为最快的马的用途就是来赢别人快的马,别人慢的马什么马都能赢。
5.当田忌最快的马比齐王最快的马慢时,拿最慢的马和齐王最快的马比,输一场,因为反正要输一场,不如拿最没用的马输。
6.当田忌最快的马和齐王最快的马相等时,这就要展开讨论了,贪心方法是,拿最慢的马来和齐王最快的马比.
前面的证明像公理样的,大家一看都能认同的,没有异议的,就不细说了。

证明:田忌最快的马和齐王最快的马相等时拿最慢的马来和齐王最快的马比有最优解。
1)假设他们有n匹马,看n=2的时候.

a1 a2
b1 b2

因为 田忌最快的马和齐王最快的马相等 所以a1=b1,a2=b2 所以这种情况有2种比赛方式,易得这两种方式得分相等。

2)当数列a和数列b全部相等等时(a1=b1,a2=b2...an=bn),显然最慢的马来和齐王最快的马比有最优解,可以赢n-1长,输1场,找不到更好的方

法了。
3)当数列a和数列b元素全部相等时(a1=b1=a2=b2...=an=bn),无法赢也不输。

因为若拿相互最快最慢的马打个平手,则田忌拿不到任何报酬,但是若输一场,让最慢的马输给国王最快的马,而在田忌的马中找任何一匹比最慢的马快一点的马去赢国王最慢的马都行,这样田忌在同样一胜一负的情况下,保留了跑得更快的马,会比把最快的马拿去比赛来得更优些。

亲情数据

/*
3
2 3 5
3 4 4

3
5 8 11
5 10 15

3
92 83 70
92 82 60

3
92 83 71
95 92 74


3
92 83 70
92 91 60

2
1 2
1 3

8
11 9 8 8 8 4 3 2
11 8 8 8 8 4 3 2

3
93 83 71
95 87 74

2
20 20
20 20

2
20 19
22 18

2
20 19
20 21

2
20 21
20 19

10
12 3 4 5 23 5 23 6 12 8
23 6 7 8 8 9 23 4 6 3

3
1 2 3
1 2 3

0
*/

数据答案

/*
0    200  400  0
200  0    800  200
0    0   -200  400
1000 200
*/

Code(java)

import java.util.*;

public class Main {

    public static int[] a = null;
    public static int[] b = null;

    public static int ans;
    public static int la, ra, lb, rb;

    public static void right_compare() {
        if (a[ra] > b[rb]) {
            ans += 200;
            ra--;
            rb--;
        }
        else if (a[ra] <= b[rb]) {
            if (a[la] < b[rb]) ans -= 200;
            la++;
            rb--;
        }
    }

    public static void left_compare() {
        if (a[la] > b[lb]) {
            ans += 200;
            la++;
            lb++;
        } else if (a[la] < b[lb]) {
            ans -= 200;
            la++;
            rb--;
        } else {
            right_compare();
        }
    }

    public static void main(String args[]) {
        Scanner in = new Scanner(System.in);
        while (in.hasNext()) {
            int n = in.nextInt();
            if (n == 0) break;
            a = new int [n];
            b = new int [n];
            for (int i = 0; i < n; i++) a[i] = in.nextInt();
            for (int i = 0; i < n; i++) b[i] = in.nextInt();
            Arrays.sort(a);
            Arrays.sort(b);

            la = lb = 0;
            ra = rb = n - 1;
            ans = 0;
            while (la <= ra && lb <= rb) {
                left_compare();
            }
            System.out.println(ans);
        }
    }

}

猜你喜欢

转载自blog.csdn.net/easylovecsdn/article/details/85215083