码迷,mamicode.com
首页 > 其他好文 > 详细

LIS

时间:2020-07-26 19:20:53      阅读:91      评论:0      收藏:0      [点我收藏+]

标签:ret   long   main   个数   ace   mem   scan   转移   const   

LIS(最长上升子序列)(含等于的是最长不上升子序列)

首先介绍下(O(n^2))的dp
首先单独一个数我们直接把他看成就是一个子序列,这个子序列的LIS就是1.我们用一个DP[i]记录从之前到i的LIS,不难得到状态转移方程dp[i]=max(dp[i],dp[j]+1) ( j=[1,i-1])
试想一下,1 3 2 5 1 4 每次跑i就找之前的子序列有没有那个子序列的最大值比a[i]还小的,有的话直接把a[i]加入,如果没有的话就把他单独弄成一个新的子序列 dp[i]=1
dp[1]=1 子序列1
dp[2]=2 子序列1 3
dp[3]=2 子序列1 3 和子序列1 2
dp[4]=3 子序列1 2 5和1 3 5
dp[5]=1 子序列就是1,之前没有找到比他小的就单独创建

#include <bits/stdc++.h>
using namespace std;
const int maxn=4e5+7;
#define  ll long long
int  a[maxn];
int  dp[maxn];
int n;
int main()
{
    scanf("%d",&n);
    for (int i=1;i<=n;++i)
    {
        scanf("%d",a+i);
    }
    int ans=0;
    memset(dp,0,sizeof (dp));
    dp[1]=1;///初始化
    for (int i=1;i<=n;++i)
    {
        for (int j=1;j<i;++j)///找寻之前的是否可以合并
        {
            if (a[i]>a[j])
            {
                ans = max(ans,dp[i]=max(dp[i],dp[j]+1));
            }
        }
        ans=max(ans,dp[i]=max(dp[i],1));///判断是否加入原来的子序列,否则直接以a[i]单独创建一个子序列
    }
    printf("%d\n",ans);
    return 0;
}

LIS

标签:ret   long   main   个数   ace   mem   scan   转移   const   

原文地址:https://www.cnblogs.com/qimang-311/p/13380082.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!