LIS最长递增子序列

给定一个长度为N的数组,找出一个最长的单调递增子序列。

例如:给定数组A{5,6,7,1,2,8},则其最长的单调递增子序列为{5,6,7,8},长度为4。

一种思路是将其转换成LCS问题:将A数组排序后:A'{1, 2, 5, 6, 7, 8}

因为,原数组A的子序列顺序保持不变,而且排序后A'本身就是递增的,这样,就保证了两序列的最长公共子序列的递增特性。如此,若想求数组A的最长递增子序列,其实就是求数组A与它的排序数组A‘的最长公共子序列。

此外,本题可以直接使用动态规划求解。

算法如下:

设长度为N的数组为{a0,a1, a2, ...an-1},则 假定以aj结尾的数组序列的最长递增子序列 长度为L(j),则L(j)={ max(L(i))+1, i<j且 a[i]<a[j] }。也就是说,我们需要遍历在j之 前的所有位置i(从0到j-1),找出满足条件 a[i]<a[j]的L(i),求出max(L(i))+1即为L(j)的 值。最后,我们遍历所有的L(j)(从0到N-1), 找出最大值即为最大递增子序列。时间复杂 度为O(N2)。 

代码如下:

  1 #include <iostream>                                                                                                               
  2 
  3 using namespace std;
  4 
  5 int LisLength(int a[], int m)
  6 {
  7     int longest[m];
  8     for(int i = 0; i < m; ++i)
  9     {
 10         longest[i] = 1;
 11     }
 12     for(int i = 1; i < m; ++i)
 13     {
 14         for(int j = 0; j < i; ++j)
 15         {
 16             if(a[j] < a[i]  && longest[i] < longest[j] + 1)
 17             {
 18                 longest[i] = longest[j] + 1;
 19             }
 20         }
 21     }
 22     int max = 1;
 23     for(int i = 0; i < m; ++i)
 24     {
 25         if(longest[i] > max)
 26         {
 27            max = longest[i];
 28         }
 29     }
 30     return max;
 31 }
 32 
 33 int main(int argc, const char *argv[])
 34 {
 35     int a[6] = {5, 6, 7, 1, 2, 0};
 36     int max = LisLength(a, 6);
 37     cout << max << endl;
 38     return 0;
 39 }

注意if判断条件,前一位小于i位,并且i位结尾的最长序列小于前一位最长序列+1,循环就一直进行下去。

posted @ 2015-04-08 21:05  bigshowxin  阅读(326)  评论(0编辑  收藏  举报