• hdu1052 Tian Ji -- The Horse Racing---田忌赛马贪心


    题目链接:

    http://acm.hdu.edu.cn/showproblem.php?pid=1052

    题目大意:

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

    思路:

    一开始贪心出错,把每匹马恰好打败稍微比自己差一点的马,后来发现这个贪心策略是错误的,比如这个例子:

    80 76

    80 75

    如果按照之前的贪心策略,第一次80需要打败75.第二次76对战80,净胜场数为0;

    但是正确的策略应该是第一次打平局,第二次胜利,净胜场数为1。

    正确思路应该是这样:

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

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

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

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

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

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

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

     1 #include<iostream>
     2 #include<algorithm>
     3 using namespace std;
     4 const int maxn = 1e5;
     5 int a[maxn], b[maxn];
     6 int main()
     7 {
     8     int n;
     9     while(cin >> n && n)
    10     {
    11         for(int i = 0; i < n; i++)
    12             cin >> a[i];
    13         for(int i = 0; i < n; i++)
    14             cin >> b[i];
    15         sort(a, a + n);
    16         sort(b, b + n);
    17         int a_low = 0 , b_low = 0, a_fast = n - 1, b_fast = n - 1;
    18         int win = 0, lose = 0;
    19         while(a_low <= a_fast)
    20         {
    21             if(a[a_low] > b[b_low])//情况1
    22             {
    23                 win++;
    24                 a_low++;
    25                 b_low++;
    26             }
    27             else if(a[a_low] < b[b_low])//情况2
    28             {
    29                 lose++;
    30                 a_low++;
    31                 b_fast--;
    32             }
    33             else//情况3
    34             {
    35                 if(a[a_fast] > b[b_fast])//最快的马可以赢,就让最快的马赢
    36                 {
    37                     win++;
    38                     a_fast--;
    39                     b_fast--;
    40                 }
    41                 else//最快的马不能赢就让最慢的马拖对面最快的马
    42                 {
    43                     if(a[a_low] < b[b_fast])//这里可能会相等,所以加一个判断条件
    44                         lose++;
    45                     a_low++;
    46                     b_fast--;
    47                 }
    48             }
    49         }
    50         int ans = 200 * (win - lose);
    51         cout<<ans<<endl;
    52     }
    53     return 0;
    54 }
  • 相关阅读:
    Union all 分别排序
    GridView中显示bool字段(在数据库中是字符类型)
    oracle语句有关知识
    验证控件验证DropDownList
    【Java高级工程师蜕变之路】013 Spring MVC基础以及高级应用
    【Java高级工程师蜕变之路】012 Spring AOP源码分析
    【Java高级工程师蜕变之路】010 Spring IOC的应用
    【Java高级工程师蜕变之路】017 Spring Data JPA的应用与源码剖析
    【Java高级工程师蜕变之路】009 手写IOC和AOP
    【Java高级工程师蜕变之路】015 Spring MVC源码剖析
  • 原文地址:https://www.cnblogs.com/fzl194/p/8682246.html
Copyright © 2020-2023  润新知