最长递增子序列(两种时间复杂度算法及其区别)+最长递减子序列(reverse)
2018-03-02 17:43
543 查看
O(n*n)//LIS+路径回溯 O(n*n)
#include <iostream>
#include<cstdio>
#include<stack>
#include<cstring>
using namespace std;
const int maxn=100+5;
int a[maxn],dp[maxn];
int parent[maxn];
int main()
{
int n;
while(scanf("%d",&n)==1&&n)
{
for(int i=0;i<n;i++)
{
scanf("%d",&a[i]);
dp[i]=1;
}
memset(parent,-1,sizeof(parent));
int res=0,ans;
for(int i=0;i<n;i++)
for(int j=0;j<i;j++)
if(a[j]<a[i]) {
if(dp[j]+1>dp[i]) {
parent[i]=j;
dp[i]=dp[j]+1;
}
if(dp[i]>res) {
ans=i;
res=dp[i];
}
}
cout<<res<<endl; //LIS长度
stack<int>s;
s.push(a[ans]);
int p=parent[ans];
while(true)
{
s.push(a[p]);
p=parent[p];
if(p==-1) break;
}
while(!s.empty())
{
cout<<s.top()<<" ";
s.pop();
}
cout<<endl;
}
return 0;
}
O(nlogn)//最长递增子序列 O(nlogn)
#include <iostream>
#include<cstdio>
#include<algorithm>
using namespace std;
const int maxn=50000+5;
const int INF=1e9+6;
int a[maxn],dp[maxn];
int main()
{
int n;
while(scanf("%d",&n)==1&&n)
{
for(int i=0;i<n;i++)
{
scanf("%d",&a[i]);
dp[i]=INF;
}
for(int i=0;i<n;i++)
{
int p=lower_bound(dp,dp+n,a[i])-dp;
dp[p]=a[i];
}
cout<<lower_bound(dp,dp+n,INF)-dp<<endl;
}
return 0;
}
注意:当使用较小时间复杂度的算法时进行路径回溯,结果可能并不正确,但最长递增子序列的长度结果是正确的
当要求的为最长递减子序列时,把原数组进行反转(reverse)操作,然后按照最长递增子序列的方法求解即可
#include <iostream>
#include<cstdio>
#include<stack>
#include<cstring>
using namespace std;
const int maxn=100+5;
int a[maxn],dp[maxn];
int parent[maxn];
int main()
{
int n;
while(scanf("%d",&n)==1&&n)
{
for(int i=0;i<n;i++)
{
scanf("%d",&a[i]);
dp[i]=1;
}
memset(parent,-1,sizeof(parent));
int res=0,ans;
for(int i=0;i<n;i++)
for(int j=0;j<i;j++)
if(a[j]<a[i]) {
if(dp[j]+1>dp[i]) {
parent[i]=j;
dp[i]=dp[j]+1;
}
if(dp[i]>res) {
ans=i;
res=dp[i];
}
}
cout<<res<<endl; //LIS长度
stack<int>s;
s.push(a[ans]);
int p=parent[ans];
while(true)
{
s.push(a[p]);
p=parent[p];
if(p==-1) break;
}
while(!s.empty())
{
cout<<s.top()<<" ";
s.pop();
}
cout<<endl;
}
return 0;
}
O(nlogn)//最长递增子序列 O(nlogn)
#include <iostream>
#include<cstdio>
#include<algorithm>
using namespace std;
const int maxn=50000+5;
const int INF=1e9+6;
int a[maxn],dp[maxn];
int main()
{
int n;
while(scanf("%d",&n)==1&&n)
{
for(int i=0;i<n;i++)
{
scanf("%d",&a[i]);
dp[i]=INF;
}
for(int i=0;i<n;i++)
{
int p=lower_bound(dp,dp+n,a[i])-dp;
dp[p]=a[i];
}
cout<<lower_bound(dp,dp+n,INF)-dp<<endl;
}
return 0;
}
注意:当使用较小时间复杂度的算法时进行路径回溯,结果可能并不正确,但最长递增子序列的长度结果是正确的
当要求的为最长递减子序列时,把原数组进行反转(reverse)操作,然后按照最长递增子序列的方法求解即可
相关文章推荐
- 设计一个O(n2)时间的算法,找出由n个数组成的序列的最长单调递增子序列。
- 算法:递归解序列中最长递减子序列
- 求最大子序列和的四种经典方法及其算法时间复杂度分析
- 最长递增子序列,时间复杂度(O(nlogn))
- 最长递增子序列,时间复杂度(O(nlogn))
- LIS(最长上升子序列两种算法模板)DP模板,并且输出序列
- 最长递增子序列,时间复杂度(O(nlogn))
- 时间复杂度为O(nlogn)的最长单调递增子序列
- 最长递增子序列,时间复杂度(O(nlogn))
- 最长递增子序列,时间复杂度(O(nlogn))
- 【难】求数组中最长递增子序列,时间复杂度O(nlogn)
- 最长递增子序列,时间复杂度(O(nlogn))
- 51nod 1134 最长递增子序列(dp) 时间复杂度为O(nlogn)
- (转载)最长递增子序列 O(NlogN)算法
- 错误的求最长递增子序列的算法实现——写完了才发现,纪念这逝去的一上午
- O(n)时间找出无序数组中最长的连续递增序列
- LIS 最长上升子序列问题 nlgn时间打印其中一个序列
- 606第七周周赛 C - Wavio Sequence最长递增递减序列
- 数组字符串那些经典算法:最大子序列和,最长递增子序列,最长公共子串,最长公共子序列,字符串编辑距离,最长不重复子串,最长回文子串
- 算法_动态规划_最长单调递增子序列问题(O(nlogn)的时间复杂度)