zoukankan      html  css  js  c++  java
  • 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):事务
    数据库(MySQL):存储引擎
    操作系统:虚拟存储器
    操作系统:内存管理
    操作系统:进程与线程
    近期目标
    计算机网络:TCP三次握手、四次挥手
    计算机网络:OSI与TCP/IP各层的结构与功能,都有哪些协议
    计算机网络:从输入URL到页面加载
    Java:JVM
  • 原文地址:https://www.cnblogs.com/qscqesze/p/4908665.html
Copyright © 2011-2022 走看看