#include <cstring>
#include <algorithm>
#include <cstdio>
using namespace std;
const int maxN=100000;
const int inf=0x3f3f3f3f;
int A[maxN+50];
int dp[maxN+50]; //dp[i]表示以A[i]为结尾时的长度
int g[maxN+50]; //g[i]表示长度为i的LIS的最小结尾值
int mem[maxN+50]; //mem[i]记录长度为i时的值
int main()
{
int n,i,MAX,maxT;
while(scanf("%d",&n)==1)
{
MAX=-1;
for (i=0;i<n;i++)
{
scanf("%d",&A[i]);
}
memset(g,0x3f,sizeof(g));
for (i=0;i<n;i++)
{
int k=lower_bound(g+1,g+n+1,A[i])-g; //因为g满足单调不减性 所以这里可以采用二分查找的方式 将O(n)复杂度降低到O(logn)
//lower_bound求严格单调递增最长子序列 upper_bound求单调不递减最长子序列
dp[i]=k;
g[k]=A[i];
if (k>MAX)
{
MAX=k;
maxT=i;
}
}
printf("%d\n",MAX);
for (i=n;i>=0 && MAX>=0 ;i--)
{
if (dp[i]==MAX)
{
printf("%d ",A[i]);
MAX--;
}
}
}
return 0;
}
【动态规划】LIS最长单调递增子序列 logn算法 并且输出子序列
最新推荐文章于 2021-02-26 19:03:10 发布