最长递增子序列
最长递增之序列简称:LIS是一道很经典的算法题,问题定义如下
给定一个无序的数组,找出长度最长的单调递增的子序列(不一定要相邻)
解法可以采用动态规划,有两种方法:
1.将源数组a 排序得到另一个数组b,然后在这两个数组中求LCS即(最长公共子序列)复杂度为 nlogn + n2
2.将源数组a直接采用动态规划,递推式很简单,如果第k位加入数组中,那么以k结尾的子序列的长度可以由(0。k-1)递推出来,即:
f(k) = max( f(j)) +1 if a[k] > a[j] 其中j<k
扩展下 如果要把LIS的序列找出来 。可以用一个N*N的数组将路径记录下来。每替换一次更新即可:
代码如下:
int LIS(int a[],int l)
{
int *buffer = new int[l];
int *index = new int[l];
int **path = new int*[l];
for(int k = 0;k<l;k++)
{
path[k] = new int[l];
memset(path[k],0,sizeof(int)*l);
}
for(int i = 0;i<l;i++)
{
int select= -1;
buffer[i] = 1;
path[i][i] = 1;
for(int j = 0;j<i;j++)
{
if(a[i]>a[j]&& buffer[i]>=buffer[j] -1)
{
buffer[i] = buffer[j] +1;
select = j;
}
}
if(select!= -1)
{
for(int h = 0;h<i;h++)
path[i][h] = path[select][h] ;
}
}
int max_path = 0;
int m = buffer[0];
for(int j =1;j<l ;j++)
if(buffer[j]>m)
{
m = buffer[j];
max_path = j;
}
for(int g= 0;g<l;g++)
{
if(path[max_path][g])
cout<<a[g]<<" ";
}
cout<<endl;
delete [] buffer;
buffer = NULL;
delete [] index;
index = NULL;
for( k = 0;k<l;k++)
{
delete [] path[k];
path[k] = NULL;
}
delete [] path;
path = NULL;
return m;
}
void main()
{
int t[]={1,5,3,4,4,5,7,4,2,5,7,8,6,4,3,3,4,5,6,7,7,7,65,34,3,3};
cout<<LIS(t,sizeof(t)/sizeof(int));
}
{
int *buffer = new int[l];
int *index = new int[l];
int **path = new int*[l];
for(int k = 0;k<l;k++)
{
path[k] = new int[l];
memset(path[k],0,sizeof(int)*l);
}
for(int i = 0;i<l;i++)
{
int select= -1;
buffer[i] = 1;
path[i][i] = 1;
for(int j = 0;j<i;j++)
{
if(a[i]>a[j]&& buffer[i]>=buffer[j] -1)
{
buffer[i] = buffer[j] +1;
select = j;
}
}
if(select!= -1)
{
for(int h = 0;h<i;h++)
path[i][h] = path[select][h] ;
}
}
int max_path = 0;
int m = buffer[0];
for(int j =1;j<l ;j++)
if(buffer[j]>m)
{
m = buffer[j];
max_path = j;
}
for(int g= 0;g<l;g++)
{
if(path[max_path][g])
cout<<a[g]<<" ";
}
cout<<endl;
delete [] buffer;
buffer = NULL;
delete [] index;
index = NULL;
for( k = 0;k<l;k++)
{
delete [] path[k];
path[k] = NULL;
}
delete [] path;
path = NULL;
return m;
}
void main()
{
int t[]={1,5,3,4,4,5,7,4,2,5,7,8,6,4,3,3,4,5,6,7,7,7,65,34,3,3};
cout<<LIS(t,sizeof(t)/sizeof(int));
}