HDU 5773 DP LIS变形

来源:互联网 发布:多维数据分析模型 编辑:程序博客网 时间:2024/06/05 20:41

题目链接

题意:一个非负序列里 0可以变成包括负数在内的任何数 问这个序列的最长严格上升子序列有多长

官方给的题解:0可以转化成任意整数,包括负数,显然求LIS时尽量把0都放进去必定是正确的。因此我们可以把0拿出来,对剩下的做O(nlogn)的LIS,统计结果的时候再算上0的数量。为了保证严格递增,我们可以将每个权值S[i]减去i前面0的个数,再做LIS,就能保证结果是严格递增的。

条件一:这个最长的上升子序列一定包含了原始序列中的全部0
证明:假设一个某个上升子序列不完全包含全部的0,这样我们可以将没有被包含的0加入这个序列中,由于0可以变为任何数,所以新序列的长度一定大于等于原序列的长度

题解没看懂……但是照着题解写 还是AC了
代码:

#include <cstdio>#include <iostream>#define sf scanf#define pf printfusing namespace std;const int maxn = 100000 + 5;int num[maxn];int g[maxn];int main(){    int T,ca = 0;    sf("%d",&T);    while( T-- ){        int n;        sf("%d",&n);        int pre_zero = 0,num_size = 0;        for(int i = 0;i < n;++i){            int temp;            sf("%d",&temp);            if(!temp) pre_zero++;            else{                num[num_size++] = temp - pre_zero;            }        }        int ans = 0;        if(!num_size){            ans = 0;        }else{            ans = 1;            g[1] = num[0];            for(int i = 1;i < num_size;++i){                if(num[i] > g[ans]){                    g[++ans] = num[i];                }                else{                    int k = lower_bound(g + 1,g + ans + 1,num[i]) - g;                    g[k] = num[i];                }            }        }        pf("Case #%d: %d\n",++ca,ans + pre_zero);    }    return 0;}
0 0
原创粉丝点击