• Codeforces Round #277 (Div. 2) E. LIS of Sequence DP


    E. LIS of Sequence

    Time Limit: 20 Sec

    Memory Limit: 256 MB

    题目连接

    http://codeforces.com/contest/486/problem/E

    Description

    The next "Data Structures and Algorithms" lesson will be about Longest Increasing Subsequence (LIS for short) of a sequence. For better understanding, Nam decided to learn it a few days before the lesson.

    Nam created a sequence a consisting of n (1 ≤ n ≤ 105) elements a1, a2, ..., an (1 ≤ ai ≤ 105). A subsequence ai1, ai2, ..., aik where 1 ≤ i1 < i2 < ... < ik ≤ n is called increasing if ai1 < ai2 < ai3 < ... < aik. An increasing subsequence is called longest if it has maximum length among all increasing subsequences.

    Nam realizes that a sequence may have several longest increasing subsequences. Hence, he divides all indexes i (1 ≤ i ≤ n), into three groups:

        group of all i such that ai belongs to no longest increasing subsequences.
        group of all i such that ai belongs to at least one but not every longest increasing subsequence.
        group of all i such that ai belongs to every longest increasing subsequence.

    Since the number of longest increasing subsequences of a may be very large, categorizing process is very difficult. Your task is to help him finish this job.

    Input

    The first line contains the single integer n (1 ≤ n ≤ 105) denoting the number of elements of sequence a.

    The second line contains n space-separated integers a1, a2, ..., an (1 ≤ ai ≤ 105).

    Output

    Print a string consisting of n characters. i-th character should be '1', '2' or '3' depending on which group among listed above index i belongs to.

    Sample Input

    4
    1 3 2 5

    Sample Output

    3223

    HINT

    题意

    给你n个数

    然后问你这里面的每个数,是否是

    1.不属于任何最长上升子序列中

    2.属于多个最长上升子序列中

    3.唯一属于一个最长上升子序列中

    题解:

    对于每一个数,维护两个dp

    dp1表示1到i的最长上升子序列长度

    dp2表示从n到i最长递减子序列长度

    然后如果dp1[i]+dp2[i] - 1 == lis ,就说明属于lis里面,如果dp1[i]的值是唯一的,就说明唯一属于一个lis

    否则就不属于咯

    代码

    #include<iostream>
    #include<stdio.h>
    #include<map>
    #include<cstring>
    #include<algorithm>
    using namespace std;
    #define maxn 100005
    int b[maxn];
    int a[maxn];
    void add(int x,int val)
    {
        while(x<=100000)
        {
            b[x] = max(b[x],val);
            x += x & (-x);
        }
    }
    int get(int x)
    {
        int ans = 0;
        while(x)
        {
            ans = max(ans,b[x]);
            x -= x & (-x);
        }
        return ans;
    }
    int dp1[maxn];
    int dp2[maxn];
    int ans[maxn];
    map<int,int> H;
    int main()
    {
        int n;scanf("%d",&n);
        int LIS = 0;
        for(int i=1;i<=n;i++)
        {
            scanf("%d",&a[i]);
            dp1[i] = 1 + get(a[i]-1);
            add(a[i],dp1[i]);
            LIS = max(LIS,dp1[i]);
        }
        reverse(a+1,a+1+n);
        memset(b,0,sizeof(b));
        for(int i=1;i<=n;i++)
        {
            a[i] = 100000 - a[i] + 1;
            dp2[i] = 1 + get(a[i] - 1);
            add(a[i],dp2[i]);
        }
        reverse(dp2+1,dp2+1+n);
        for(int i=1;i<=n;i++)
        {
            if(dp1[i]+dp2[i]-1!=LIS)ans[i]=1;
            else H[dp1[i]]++;
        }
        for(int i=1;i<=n;i++)
        {
            if(ans[i]!=1&&H[dp1[i]]==1)
            {
                ans[i]=3;
            }
        }
        for(int i=1;i<=n;i++)
            if(ans[i]==1)
                cout<<"1";
            else if(ans[i]==0)
                cout<<"2";
            else if(ans[i]==3)
                cout<<"3";
    }
    /*
    10
    2 2 2 17 8 9 10 17 10 5
    */
  • 相关阅读:
    实战:推断mysql中当前用户的连接数-分组筛选
    Codeforces Round #250 (Div. 2) A
    设计模式(3)-对象创建型模式-Abstract Factory模式
    设计模式
    uva 11825 Hackers&#39; Crackdown (状压dp,子集枚举)
    java中不常见的keyword:strictfp,transient
    C++中数组初始化
    Hadoop 开源调度系统zeus(二)
    Python发一个GET请求
    【代码优化】equals深入理解
  • 原文地址:https://www.cnblogs.com/qscqesze/p/4908665.html
Copyright © 2020-2023  润新知