问题描述:
在数字列A={a1,a2….an}中按递增下标序列顺序选出一个子序列B,如果B中的数严格递增,则序列B为A的递增子序列。现给你一个数字序列,求出他的最长递增子序列。(只要求下标递增,不要求连续)。
分析:
用L[i]记录a1~ai的最长递增子序列的长度,初始值都为1。当求L[i]时,L[i]的值等于下标值j在i之前的(j< i)且a[j]< a[i]的L[j]+1的最大值。所以每次只用扫描a[1]~a[i-1]即可。用X[i][n]记录下标为a[i]的最长子序列。
#include <iostream>
using namespace std;
const int MAXN=1005;
int a[MAXN],L[MAXN],X[MAXN][MAXN];
int IncreaseOrder(int n);
int main()
{
int n,i;
cin>>n;
for(i=0;i<n;i++)
cin>>a[i];
cout<<IncreaseOrder(n)<<endl;
return 0;
}
int IncreaseOrder(int n)
{
int i,j,k,index;
for(i=0;i<n;i++)
{
L[i]=1;
}
for(i=1;i<n;i++)
{
int maxL = 1;
int dj;
for(j=i-1;j>=0;j--)
{
if(a[j]<a[i] && L[j]+1>maxL)
{
maxL=L[j]+1;
dj=j;
}
}
L[i] = maxL;
for(k=0;k<maxL-1;k++)
X[i][k] = X[dj][k];
X[i][maxL-1] = a[i];
}
index = 0;
for(i=1;i<n;i++)
if(L[i]>L[index])
index = i;
cout<<"最长递增子序列:"<<endl;
for(i=0;i<L[index];i++)
cout<<X[index][i]<<" ";
cout<<endl;
return L[index];
}
若有多个最长递增子序列,该算法只是输出了第一个最长的递增子序列,若要输出全部的或者字典序最小的,只需做稍微的添加控制即可。