2017年南宁网络赛 L 题 【最长非递减序列 + 思维】

传送门
//题意: 就是给你一串数字, 如果它是负数那么它的权重为0, 如果它>=1e4, 那么它的权重为5, 且在序列中真正的数是该数 - 1e4. 其他的数权重为1. 问选一个权重最大的LIS.
//思路: 我们首先考虑nlogn的LIS的做法, 其中的g数组保存的是以该个数结尾的最长的LIS是多少, 并且越小的越好. 那么是不是跟这个很像了. 所以直接权重为5的连续插入5次, 然后求一个最长的非递减序列, 所以直接将lower_bound 改成 upper_bound就可以啦! 具体请看代码.

AC Code

const int maxn = 2e6+5;
int cnt;
int num[maxn],g[maxn];
int LIS()
{
    Fill(g,inf);
    int maxlen = 0;
    for(int i=1;i<=cnt;i++){
        int pos = upper_bound(g+1,g+1+cnt,num[i]) - g;
        g[pos] = num[i];
        maxlen = max(maxlen,pos);
    }
    return maxlen;
}

void solve()
{
    int x;
    cnt = 1;
    while(~scanf("%d",&x)){
        if(x < 0 ) continue;
        if(x >= 10000) {
            for(int i=1;i<=5;i++){
                num[cnt++] = x - 10000;
            }
        }
        else num[cnt++] = x;
    }
    printf("%d\n",LIS());
}

你可能感兴趣的:(序列dp)