• CSU 1551 Longest Increasing Subsequence Again(树状数组 或者 LIS变形)


    题目链接:http://acm.csu.edu.cn/csuoj/problemset/problem?pid=1551

    升级版:Uva 1471

    题意:

      让你求删除一段连续的子序列之后的LIS。

    题解:  

      预处理:先求一个last[i],以a[i]为开始的合法最长上升子序列的长度。再求一个pre[i],以a[i]为结尾的合法最长上升子序列长度。

      答案应该为 

      max(以j结束的合法最长上升子序列长度) + 以a[i]为开始的合法最长上升子序列长度。 其中j<a[i]。

      1)通过树状数组维护区间最值。

      2)通过LIS 维护。(详细请看http://www.cnblogs.com/denghaiquan/p/6761600.html

     1 #include <iostream>
     2 #include <cstdio>
     3 #include <cstring>
     4 #include <cstdlib>
     5 #include <string>
     6 #include <vector>
     7 #include <map>
     8 #include <set>
     9 #include <queue>
    10 #include <sstream>
    11 #include <algorithm>
    12 using namespace std;
    13 #define pb push_back
    14 #define mp make_pair
    15 #define ms(a, b)  memset((a), (b), sizeof(a))
    16 //#define LOCAL
    17 #define eps 0.0000001
    18 typedef long long LL;
    19 const int inf = 0x3f3f3f3f;
    20 const int maxn = 10000+10;
    21 const int mod = 1000000007;
    22 int a[maxn], pre[maxn], last[maxn], c[maxn];
    23 int n;
    24 int lowbit(int x){
    25     return x&(-x);
    26 }
    27 int ask(int x)
    28 {
    29     int ans = 0;
    30     while(x>0){
    31         ans = max(ans, c[x]);
    32         x-=lowbit(x);
    33     }
    34     return ans;
    35 }
    36 void updata(int x, int d)
    37 {
    38     while(x <= 1e4){
    39         c[x] = max (c[x] , d);
    40         x += lowbit(x);
    41     }
    42 }
    43 void solve()
    44 {
    45     int ans = 0;
    46     ms(c, 0);
    47     for(int i=1;i<=n;i++)    scanf("%d", &a[i]);
    48     //last[i] 是第i个开始和合法后缀
    49     last[n] = 1;
    50     for(int i = n-1; i>0;i--){
    51         if(a[i] < a[i+1]){
    52             last[i] = last[i+1] + 1;
    53         }else   last[i] = 1;
    54     }
    55     //pre[i] 是第i个结束的合法前缀
    56     pre[1] = 1;
    57     for(int i=2;i<=n;i++){
    58         if(a[i] > a[i-1]){
    59             pre[i] = pre[i-1] + 1;
    60         }else   pre[i] = 1;
    61     }
    62     for(int i=1;i<=n;i++){
    63         ans = max(ans, last[i] + ask(a[i]-1));
    64         updata(a[i], pre[i]);
    65     }
    66     printf("%d
    ", ans);
    67 }
    68 int main()
    69 {
    70     #ifdef LOCAL
    71         freopen("jumping.in", "r", stdin);
    72 //      freopen("output.txt", "w", stdout);
    73     #endif // LOCAL
    74     while(~scanf("%d", &n)){
    75         solve();
    76     }
    77     return 0;
    78 }
    View Code

    升级版,应该数的范围在1e9所以无法用树状数组维护。只能用LIS或者set来维护。

  • 相关阅读:
    Android studio快捷键大全 和 eclipse对照(原)
    .net 提取注释生成API文档 帮助文档
    查看443端口被占用无法启动解决办法
    关于正则表达式 C#
    关于 ImageLoader 说的够细了。。。
    什么时候用Application的Context,什么时候用Activity的Context
    关于layoutparam 请铭记。。。。
    java 静态方法上的泛型
    让多个Fragment 切换时不重新实例化
    开源.net 混淆器ConfuserEx介绍
  • 原文地址:https://www.cnblogs.com/denghaiquan/p/6761710.html
Copyright © 2020-2023  润新知