写一个时间复杂度尽可能低的程序,求一个一维数组N个元素中最长递增子序列的长度.
题目:
设L=<a1,a2,…,an>是n个不同的实数的序列,L的递增子序列是这样一个子序列Lin=<aK1,ak2,…,akm>,其中k1<k2<…<km且aK1<ak2<…<akm。求最大的m值。
如:序列:1,-1,2,-3,4,-5,6,-7中最长递增子序列的长度为:1,2,4,6
方法一:
动态规划:O(N^2)
阶段间的关系具有无后效性。阶段:在所有元素的子数组中,选出其中的最长递增子序列,k=1,2...N。
状态:以元素k结尾的最长递增子序列中只有一个最长的递增子序列。
决策:决定元素k结尾的最长递增子序列有k-1种获取的途径,前面以任何一个元素结尾的最长递增子序列都可能成为其的一部分。
#include<iostream>
using namespace std;
int LIS(int num[],int N);
int main()
{
int N ,i;
int *num;
cout<<"请输入数组中元素的个数: " ;
cin>>N;
num=(int *)malloc(sizeof(int)*(N+1));
cout<<"请输入" <<N<<"个元素"<<endl;
for (i=0;i<N;i++)
{
cin>>num[i];
}
cout<<"最长子序列的长度为 : " <<LIS(num,N)<<endl;
return 0;
}
int LIS(int num[],int N)
{
int X;
int i,k;
int *lis;
lis=(int *)malloc(sizeof(int)*(N+1));
//DP 阶段、 状态、决策
for (i=0;i<N;i++)//阶段
{
lis[i]=1;//每个阶段只有一个状态
for (k=0;k<i;k++)// 每个状态有i种决策,得出以元素i结尾的最长递归子序列的长度
{
if (((lis[k]+1)>lis[i])&&(num[i]>num[k]))
{
lis[i]=lis[k]+1;
}
}
}
X=lis[0];
for (i=1;i<N;i++)
{
if (X<lis[i])
{
X=lis[i];
}
}
return X;
}