LIS
Posted qimang-311
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了LIS相关的知识,希望对你有一定的参考价值。
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
",ans);
return 0;
}
以上是关于LIS的主要内容,如果未能解决你的问题,请参考以下文章