• HDU 1052 Tian Ji The Horse Racing


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

    题目内容就是田忌赛马,解决思路就是贪心,关键是要怎么贪,。

    我在看完题目后想到一种方法,就是田忌速度最大的马开始,尽量和速度最接近的马来比,这样结果无非就是平局或获胜,无法匹配的马就当输了。

    本以为这样可以减少马“性能”上的浪费,就能得到最优解。但有组数据就能当反例:

    3
    92 83 70
    92 91 60

    按照我的算法,92和92 配对,83就只能和60配了。最优的是92和91配,83和60配。

    我的算法关键就错在对于平局是可以有两种方法的,但我只处理了一种。

    下面来正确的:

      1.当田忌最慢的马比齐王最慢的马快,赢一场先。
        如果不赢,最慢的马可能就比不上KING第二慢的马;符合“性能”上的节约。
      2.当田忌最慢的马比齐王最慢的马慢,和齐王最快的马比,输一场。
        既然一定会输,何不“带”死对方最厉害的?
      3.如果一样快:
        1.当田忌最快的马比齐王最快的马快时,赢一场先。符合“性能”上的节约。
        2.当田忌最慢的马比齐王最快的马慢时,拿最慢的马和齐王最快的马比,输一场。
          最难理解的就是这条了!关键这里包括最快的马平局的情况,为什么要故意输一场?
          拿最慢的马带死King最快的马,
    那么自己最快的马肯定能赢king的下一匹马,
          自己第二慢的马肯定能赢King最慢的马,补回来了!剩下的好理解了。

        3.当田忌最慢的马和齐王最快的马相等时,拿最慢的马来和齐王最快的马比。平局。

    其实也可以先从两人最快的马开始考虑,只要当前的选肯定是最优的就行了。

    AC代码:

     1 #include <stdio.h>
     2 #include <stdlib.h>
     3 
     4 int cmp(const void *a,const void *b)
     5 {
     6     return *(int*)a-*(int*)b;
     7 }
     8 
     9 int a[1002],b[1002];
    10 inline void read(int *p,int n)
    11 {
    12     for (int i=0; i<n; ++i) scanf("%d",p+i);
    13 }
    14 int main()
    15 {
    16     int n;
    17     while (~scanf("%d",&n) && n)
    18     {
    19         read(a,n);
    20         read(b,n);
    21         qsort(a,n,sizeof(a[0]),cmp);
    22         qsort(b,n,sizeof(b[0]),cmp);
    23         int ans=0;
    24         int i=0,j=0,in=n-1,jn=n-1;
    25         while(i<=in)
    26         {
    27             if (a[i]>b[j]) {++ans;++i;++j;continue;}
    28             if (a[i]<b[j]) {--ans;++i;--jn;continue;}
    29             if (a[in]>b[jn]) {++ans;--in;--jn;continue;}
    30             if (a[i]<b[jn]) --ans;
    31             ++i;--jn;
    32         }
    33         printf("%d\n",ans*200);
    34     }
    35 }

    当然这题也有DP的解法:

       用f[i][j]表示齐王出第i匹马,田忌在前面(速度慢的马)选了j匹马(后面选了i-j匹马)的最优值

       由此可见,当前齐王出得马是i号马,田忌要么出j号马,要么出从后数的第i-j匹马,总共有n匹马的话,
       从后数第i-j匹马就是从前数的第n-(i-j)+1号马,所以说当前田   忌要么拿j马和齐王i马比要么拿n-(i-j)+1号马和齐王比。
        f[i][j]的值就在这两种决策中选个最优

  • 相关阅读:
    [转]C#里 泛型Where和 new()的使用
    测试
    C#中的static、readonly与const的比较
    将字符串格式化变为两位
    在VS中对字段进行包装
    安装mysql的心得
    关于mysql数据库的乱码问题
    timestamp的两个属性:CURRENT_TIMESTAMP 和ON UPDATE CURRENT_TIMESTAMP
    解决向数据库mysql插入double数据小数点不显示问题
    JDBOOK
  • 原文地址:https://www.cnblogs.com/wuminye/p/2785055.html
Copyright © 2020-2023  润新知