{问题描述]
例如,对于序列[3, 7, 1, 5, 9, 3],其中最长有序子序列长度为3,这样的子序列有:
[3, 7, 9]、[1, 5, 9]、[3, 5, 9]。
找出由n个元素组成的序列的最长有序子序列长度及其中一个最长有序子序列
(注:这里有序指非递减顺序,且不要求子序列连续)。例如,对于序列[3, 7, 1, 5, 9, 3],其中最长有序子序列长度为3,这样的子序列有:
[3, 7, 9]、[1, 5, 9]、[3, 5, 9]。
[算法思想]
利用动态规划的思想,依次处理序列中每个元素,并记录当前已处理序列的结果。
利用动态规划的思想,依次处理序列中每个元素,并记录当前已处理序列的结果。
分析:
假设有数组a,长度为n,从0到n-1,定义的二维数组x是用来存放最大递增子序列的每个元素的,即x[i][j]i表示是遍历到a[i-1]时,然后每行是用来存放递增的各个具体的元素,定义的一维数组l[]是用来存放每个最大递增子序列的长度的,初始化时l[i]应该都是1,当遍历到i时,假如满足a[i]>a[j]且l[i]<l[j]+1;时则l[i]=l[j]+1,同时还要用x[][]来存储有序的这些具体元素,把j行的元素移到i行,而且最后一个再放a[i];自己做时可以试着跟着程序画个二维数组就明白原理了
算法复杂度为O(n^2),对于优化的算法 暂时还不太清楚,正在学习中
代码实现:
#include<iostream>
using namespace std;
void lis(int a[],int n)
{
int x[10][10];
int i,j,t,index;
int l[10];
for(i=0;i<n;i++)
{
x[i][0]=a[i];
l[i]=1;
}
for(i=1;i<n;i++)
{
int max=1;//忘了定义max
for(j=i-1;j>=0;j--)
{
if(a[j]<a[i] && max<l[j]+1)
{
max=l[j]+1;
l[i]=max;
for(t=0;t<max-1;t++)
x[i][t]=x[j][t];
x[i][max-1]=a[i];
}
}
}
for(index=0,i=1;i<n;i++)
{
if(l[index]<l[i]) index=i;
}
cout<<l[index]<<endl;
for(i=0;i<l[index];i++)
cout<<x[index][i]<<" ";
cout<<endl;
}
int main()
{
int a[10];
int n,i,j;
cin>>n;
for(i=0;i<n;i++)
{
cin>>a[i];
}
lis(a,n);
cin>>j;
return 0;
}
using namespace std;
void lis(int a[],int n)
{
int x[10][10];
int i,j,t,index;
int l[10];
for(i=0;i<n;i++)
{
x[i][0]=a[i];
l[i]=1;
}
for(i=1;i<n;i++)
{
int max=1;//忘了定义max
for(j=i-1;j>=0;j--)
{
if(a[j]<a[i] && max<l[j]+1)
{
max=l[j]+1;
l[i]=max;
for(t=0;t<max-1;t++)
x[i][t]=x[j][t];
x[i][max-1]=a[i];
}
}
}
for(index=0,i=1;i<n;i++)
{
if(l[index]<l[i]) index=i;
}
cout<<l[index]<<endl;
for(i=0;i<l[index];i++)
cout<<x[index][i]<<" ";
cout<<endl;
}
int main()
{
int a[10];
int n,i,j;
cin>>n;
for(i=0;i<n;i++)
{
cin>>a[i];
}
lis(a,n);
cin>>j;
return 0;
}