zoukankan      html  css  js  c++  java
  • HDUOJ-----4512吉哥系列故事——完美队形I(LCIS)

    吉哥系列故事——完美队形I

    Time Limit: 3000/1000 MS (Java/Others)    Memory Limit: 65535/32768 K (Java/Others)
    Total Submission(s): 1894    Accepted Submission(s): 568


    Problem Description
      吉哥这几天对队形比较感兴趣。
      有一天,有n个人按顺序站在他的面前,他们的身高分别是h[1], h[2] ... h[n],吉哥希望从中挑出一些人,让这些人形成一个新的队形,新的队形若满足以下三点要求,则称之为完美队形:
      
      1、挑出的人保持他们在原队形的相对顺序不变;
      2、左右对称,假设有m个人形成新的队形,则第1个人和第m个人身高相同,第2个人和第m-1个人身高相同,依此类推,当然,如果m是奇数,中间那个人可以任意;
      3、从左到中间那个人,身高需保证递增,如果用H表示新队形的高度,则H[1] < H[2] < H[3] .... < H[mid]。

      现在吉哥想知道:最多能选出多少人组成完美队形?
     
    Input
      第一行输入T,表示总共有T组数据(T <= 20);
      每组数据先输入原先队形的人数n(1<=n <= 200),接下来一行输入n个整数,表示按顺序从左到右原先队形位置站的人的身高(50 <= h <= 250,不排除特别矮小和高大的)。
     
    Output
      请输出能组成完美队形的最多人数,每组数据输出占一行。
     
    Sample Input
    2
    3
    51 52 51
    4
    51 52 52 51
    Sample Output
    3
    4
     
    Source
       借助这道题,不如讲讲最长公共子序列吧!
    首先要区分最长公共子序列(lcs)和最长公共字串(lcs)....
    对于系列
             a<x1,x2,x3,x4,x5,x6.....x7> ,
             b<y1,y2,y3,y4,y5,y6......y7>;
    不如看看伪代码吧:
    start length_a , length_b,lcs[legth_a][length_b];
         for : i  from 1 to length_a ;
              for : j  from 1 to legth_b ;
                 if  a[i] == b[j] 
                          lcs[i][j] = lcs[i][j]+1;
             else  
                   if a[i]!=b[j] 
                        lcs[i][j] = max { lcs[i][j-1] , lcs[i-1][j]} ;
          end for ;
          end for ;
         return lcs[length_a][length_b] ;
    end

    c++实现代码:

     1 int Lcs(int aa[] ,int bb[] ,int la ,int lb)
     2 {
     3    int cc[la][lb];
     4    menset(cc,0,sizeof(cc));  
     5    for(i=1;i<=la ; i++)
     6   {
     7      for(j=1 ; j<=lb ;j++)
     8      {
     9        if(aa[i]==bb[j])
    10           cc[i][j]=cc[i-1][j-1]+1;
    11       if(aa[i]!=bb[j])
    12      {
    13          cc[i][j]= cc[i][j-1]>cc[i-1][j]? cc[i][j-1]:cc[i-1][j];
    14      }
    15       }
    16   }
    17  return cc[la][lb];
    18 }

    对于对递增函数:

    就如同这道题:

     

    看看这道题的代码:

     1     //lcis algorithm
     2     #include<stdio.h>
     3     #include<string.h>
     4     #define maxn 205
     5     int aa[maxn];
     6     int lcs[maxn];
     7     int main()
     8     {
     9         int test,n,i,j,maxc,w,res;
    10         scanf("%d",&test);
    11         while(test--)
    12          {
    13              scanf("%d",&n);
    14              for(i=1;i<=n;i++)
    15                   scanf("%d",aa+i);
    16              res=0;
    17              memset(lcs,0,sizeof(lcs));
    18              for(i=1;i<=n;i++)
    19              {
    20                  maxc=0;
    21                  for( j=n;j>=i;j--)   //每一次重边一次
    22                  {
    23                      if(aa[i]==aa[j]&&lcs[j]<maxc+1)
    24                             lcs[j]=maxc+1;
    25                     else
    26                        if(aa[i]>aa[j]&&maxc<lcs[j])
    27                              maxc=lcs[j];
    28                      //如何判断是否为重边
    29                      if(i<j)
    30                      {
    31                          if(res<2*lcs[j])
    32                              res=2*lcs[j];
    33                      }
    34                      else   //重边
    35                      {
    36                          if(res<2*lcs[j]-1)
    37                             res=2*lcs[j]-1;
    38                      }
    39                  }
    40              }
    41               printf("%d
    ",res);
    42              }
    43         return 0;
    44     }

     可以使用简化过程,减少空间开销...

    代码如下:

     1 #include<stdio.h>
     2 #include<string.h>
     3 int aa[202],bb[202];
     4 int lcs[202];
     5 int main()
     6 {
     7     int test,n,i,j,k;
     8      int ans=0;
     9     scanf("%d",&test);
    10     while(test--)
    11     {
    12        scanf("%d",&n);
    13        for(i=1;i<=n;i++)
    14         {
    15           scanf("%d",aa+i);
    16           bb[n-i+1]=aa[i];
    17         }
    18            ans=0;
    19            memset(lcs,0,sizeof(lcs));
    20             for(i=1;i<=n;i++)
    21             {
    22               k=0 ;
    23               for(j=1;j+i<=n+1;j++)   //每次覆盖一
    24               {
    25                if(aa[i]==bb[j]&&lcs[k]+1>lcs[j])
    26                     lcs[j]=lcs[k]+1;
    27                if(aa[i]>bb[j]&&lcs[j]>lcs[k]) k=j;
    28                if(i+j==n+1)
    29                {
    30                    if(aa[i-1]<bb[j]&&ans<2*lcs[j]-1)
    31                          ans=2*lcs[j]-1;
    32                }
    33                else
    34                   if(ans<2*lcs[j])
    35                         ans=2*lcs[j];
    36               }
    37             }
    38             //判断隔板上的点是否为最大
    39         printf("%d
    ",ans);
    40     }
    41     return 0;
    42 }
  • 相关阅读:
    JS加密对应的c#解码
    Content-Type: application/www-form-urlencoded
    使用abcpdf分页设置的问题
    Windows10远程报错:由于CredSSP加密Oracle修正
    ueditorUE 去掉本地保存成功的提示框!
    js进制转换
    缓存穿透 缓存雪崩 缓存击穿
    DTcms 模版用vs2015或2017 打开编辑时候 粘贴出问题 代码被调整
    通俗简述 依赖倒置•控制反转•依赖注入•面向接口编程 的思想
    tcp/ip
  • 原文地址:https://www.cnblogs.com/gongxijun/p/3632322.html
Copyright © 2011-2022 走看看