LIS 的模板

来源:互联网 发布:薛之谦和李荣浩 知乎 编辑:程序博客网 时间:2024/05/16 07:47

代码来自别人的博客

先是比较简单的版本

const int MAXN = 1010;int n;int a[MAXN];int dp[MAXN];int lis(){    memset(dp, 0, sizeof(dp));    int Max;    for (int i = 0; i < n; ++i)    {        Max = 0;        for (int j = 0; j < i; ++j)        {            if (a[i] > a[j])            {                Max = max(Max, dp[j]);            }        }        dp[i] = Max + 1;    }    Max = 0;    for (int i = 0; i < n; ++i)    {        if (dp[i] > Max)    Max = dp[i];    }    return Max;}

然后是常用到的n*logn的算法

const int MAXN = 1010;int n;int a[MAXN];int dp[MAXN];int lis(){    memset(dp, 0, sizeof(int)*n);    int len = 1;    dp[0] = a[0];    for (int i = 1; i < n; ++i)    {        int pos = lower_bound(dp, dp + len, a[i]) - dp;        dp[pos] = a[i];        len = max(len, pos + 1);    }    return len;}

上面的都是求严格递增的最大上升子序列
如果题目有变形如果求最大上升子序列的话,我自己也给个模板,巨巨教我的

int calc(int sign){    fill(dp,dp+maxn,inf);    int ans = 0;    for(int i=0;i<n;i++){        int index = upper_bound(dp,dp+ans,a[i]*sign) - dp;//这个是求不严格的序列,如果要求严格的就用lower_bound        dp[index] = a[i]*sign;        ans = max(ans,index+1);    }    return ans;}int lins(){    return calc(1);// 求上升的}int lnds(){    return calc(-1);//求下降的}

加油~~

0 0
原创粉丝点击