• hdu 4604 Deque


    题意:给出N个数A_1 to A_N和一个双向队列(两头都可以push),按顺序从N个数中取数,取出的数要么丢弃,要么从队列一端压入。队列中的数要求是不降。求最多能放入多少个数。

    思路:由于A_1 to A_N是按顺序取,因此可以从右往左求最长不增子序列a[i]和最长不降子序列b[i],然后枚举每个数作为第一个放入的元素,得到a[i]+b[i]-1。但是这还不是答案,因为两个序列是不降和不增,虽然从同一个数开始递增递减,类似 4 4 3 2 1 5 这样的数列,第二个4就计算重复了,所以要处理一下,减去重复的数。

    求最长不增序列和最长不降序列要用O(nlogn算法)。

      1 #include <cstdio>
      2 #include <cstring>
      3 #define N 100005
      4 
      5 int d[N], a[N], b[N], n, aa[N], bb[N], t1[N], t2[N];
      6 
      7 int bs(int x, int len)
      8 {
      9     int l = 1, r = len, mid;
     10     while(l<r)
     11     {
     12         mid = (l + r) / 2;
     13         if(x<a[mid]) r = mid;
     14         else if(x>=a[mid]) l = mid + 1;
     15     }
     16     return l;
     17 }
     18 
     19 int bs2(int x, int len)
     20 {
     21     int l = 1, r = len, mid;
     22     while(l<r)
     23     {
     24         mid = (l + r) / 2;
     25         if(x>b[mid]) r = mid;
     26         else if(x<=b[mid]) l = mid + 1;
     27     }
     28     return l;
     29 }
     30 
     31 int main()
     32 {
     33     int t;
     34     scanf("%d",&t);
     35     while(t--)
     36     {
     37         memset(t1, 0sizeof(t1));
     38         memset(t2, 0sizeof(t2));
     39         scanf("%d",&n);
     40         for(int i=1; i<=n; i++)
     41             scanf("%d",&d[i]);
     42         int len1 = 1;
     43         a[1] = d[n];
     44         aa[n] = 1;
     45         for(int i=n-1; i>=1; i--)
     46         {
     47             if(d[i]>=a[len1])
     48             {
     49                 a[++len1] = d[i];
     50                 aa[i] = len1;
     51             }
     52             else
     53             {
     54                 int pos = bs(d[i],len1);
     55                 aa[i] = pos; //前i个数的最长不降子序列长度为pos
     56                 a[pos] = d[i];
     57             }
     58         }
     59 
     60         int len2 = 1;
     61         b[1] = d[n];
     62         bb[n] = 1;
     63         for(int i=n-1; i>=1; i--)
     64         {
     65             if(d[i]<=b[len2])
     66             {
     67                 //printf("b:%d ",i);
     68                 b[++len2] = d[i];
     69                 bb[i] = len2;
     70             }
     71             else
     72             {
     73                 int pos = bs2(d[i],len2);
     74                 bb[i] = pos;
     75                 b[pos] = d[i];
     76             }
     77         }
     78         int ans = 0, aid = -1;
     79         for(int i=1; i<=n; i++)
     80         {
     81             int tmp = aa[i] + bb[i] - 1;
     82             if(ans<tmp)
     83             {
     84                 ans = tmp;
     85                 aid = i;
     86             }
     87         }
     88 
     89         for(int i=aid+1; i<=n; i++)
     90         {
     91             if(d[i]==d[aid])
     92             {
     93                 t1[aa[aid]-aa[i]]++;
     94                 t2[bb[aid]-bb[i]]++;
     95             }
     96         }
     97         for(int i=1; i<=n; i++)
     98         {
     99             if(t1[i]==1 && t2[i]==1) ans--;
    100         }
    101         printf("%d ",ans);
    102     }
    103     return 0;
    104 }
    View Code
  • 相关阅读:
    vue bus 中央事件总线
    0时间复杂度
    stack 数据结构
    es6 class
    directives 自定义指令
    node中间件
    数据结构博客清单
    TCP/IP 协议栈博客清单
    Java 面向对象:接口
    Java 面向对象:Object 类
  • 原文地址:https://www.cnblogs.com/byluoluo/p/3584227.html
Copyright © 2020-2023  润新知