zoukankan      html  css  js  c++  java
  • hdu 4604 Deque

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

    想了半天,发现是LIS,O(nlgn)飘过。

    具体思路:预处理好以i为开头的(下面我用逆序输入,所以是以i为结尾的)LIS和LDS。

         再枚举每个点找最优即可(注意不严格递增、减)。

      1 #include<map>
      2 #include<set>
      3 #include<list>
      4 #include<cmath>
      5 #include<ctime>
      6 #include<queue>
      7 #include<stack>
      8 #include<cctype>
      9 #include<cstdio>
     10 #include<string>
     11 #include<vector>
     12 #include<cstdlib>
     13 #include<cstring>
     14 #include<iostream>
     15 #include<algorithm>
     16 #define MAXN 100005
     17 using namespace std;
     18 int num[MAXN], n;
     19 int dpI[MAXN], lenI[MAXN];    //I:increasing
     20 int dpD[MAXN], lenD[MAXN];    //D:decreasing
     21 int cntI[MAXN], cntD[MAXN];    
     22 //cnt[i]记录以i结尾的子序列中num[i]的重复个数。
     23 
     24 int searchI(int x)
     25 {
     26     //printf("done
    ");
     27     int l=1, r=n, m;
     28     while(l <= r)
     29     {
     30         m = (l+r)/2;
     31         if(x >= lenI[m])
     32             l = m+1;
     33         else
     34             r= m-1;
     35     }
     36     return l-1;
     37 }
     38 
     39 int searchD(int x)
     40 {
     41     int l=1, r=n, m;
     42     while(l <= r)
     43     {
     44         m = (l+r)/2;
     45         if(x <= lenD[m])
     46             l = m+1;
     47         else
     48             r= m-1;
     49     }
     50     return l-1;
     51 }
     52 
     53 void print(int *x)
     54 {
     55     for(int i=1; i<=n; i++)
     56         printf("%d ", x[i]);
     57     printf("
    ");
     58 }
     59 
     60 int main()
     61 {    
     62     //hdu 1005
     63     int t;
     64     cin >> t;
     65     while(t--){
     66         cin >> n;
     67         for(int i=n; i>=1; i--)
     68             scanf("%d", &num[i]);
     69         //为了方便处理,逆序输入。
     70         memset(lenI, 0x3f, sizeof(lenI));
     71         for(int i=1; i<=n; i++){
     72             lenD[i] = -0x3f3f3f3f;
     73             cntI[i] = cntD[i] = 1;
     74         }
     75         
     76         for(int i=1; i<=n; i++){
     77             int k = searchI(num[i]);
     78             dpI[i] = k + 1;
     79             if(lenI[k] == num[i])
     80                 cntI[k+1] = cntI[k]+1;
     81             lenI[dpI[i]] = min(lenI[dpI[i]], num[i]);    
     82         }
     83         
     84         for(int i=1; i<=n; i++){
     85             int k = searchD(num[i]);
     86             dpD[i] = k + 1;
     87             if(lenD[k] == num[i])
     88                 cntD[k+1] = cntD[k]+1;
     89             lenD[dpD[i]] = max(lenD[dpD[i]], num[i]);
     90         }
     91         //print(dpI);
     92         //print(dpD);
     93         
     94         int ans = 0;
     95         for(int i=1; i<=n; i++)
     96             ans = max(ans, dpI[i]+dpD[i]-min(cntI[i], cntD[i]));
     97         printf("%d
    ", ans);
     98         
     99     }
    100 
    101     return 0;
    102 }
    View Code

    可以做一下类似题:EOJ 1237   O(n^2)水过

    http://www.acm.cs.ecnu.edu.cn/problem.php?problemid=1237

  • 相关阅读:
    从操作系统拖拽图片到指定区域进行预览
    原生拖拽,拖放事件(drag and drop)
    H5原生拖拽事件
    css3滚动提示
    通过模糊来弱化背景
    js获取url的各项参数
    垂直居中 解决方法
    紧贴底部的页脚
    实现html元素跟随touchmove事件的event.touches[0].clientX移动
    前端方面值得尊敬的大神们
  • 原文地址:https://www.cnblogs.com/KimKyeYu/p/3212591.html
Copyright © 2011-2022 走看看