最长递增子序列

来源:互联网 发布:眸倾天下网络续集结局 编辑:程序博客网 时间:2024/06/01 07:13

最长递增子序列又叫做最长上升子序列;子序列,正如LCS一样,元素不一定要求连续。本节讨论实现三种常见方法,主要是练手。

题:求一个一维数组arr[i]中的最长递增子序列的长度,如在序列1,-1,2,-3,4,-5,6,-7中,最长递增子序列长度为4,可以是1,2,4,6,也可以是-1,2,4,6。

方法一:DP

像LCS一样,从后向前分析,很容易想到,第i个元素之前的最长递增子序列的长度要么是1(单独成一个序列),要么就是第i-1个元素之前的最长递增子序列加1,可以有状态方程:

LIS[i] = max{1,LIS[k]+1},其中,对于任意的k<=i-1,arr[i] > arr[k],这样arr[i]才能在arr[k]的基础上构成一个新的递增子序列。

#include "iostream"#include "vector"#include "ctime"#include "cstdlib"using namespace std;std::vector<int> maxlen;int lislen;void LIS(const vector<int> &a){lislen = 1;for (int i = 1; i < a.size(); ++i){for (int j = 0; j < i; ++j){if(a[i] > a[j] && maxlen[i] < maxlen[j] + 1){maxlen[i] = maxlen[j] + 1;if(maxlen[i] > lislen){lislen = maxlen[i];}}}}}void printLIS(const vector<int> &a){std::vector<int> lis;int index = a.size() - 1;cout<<lislen<<endl;while(index >= 0 && lislen > 0){if(maxlen[index] == lislen){//此时a[index]属于LISlis.push_back(a[index]);lislen--;}--index;}for (int i = lis.size() - 1; i >= 0; --i){cout<<lis[i]<<"\t";}cout<<endl;}int main(int argc, char const *argv[]){const int N = 10;std::vector<int> a(N);maxlen.resize(N,1);//第一次字符的LIS长度为1srand(time(0));for (int i = 0; i < N; ++i){int rand_num = rand()%100;a[i] = rand_num;cout<<rand_num<<"\t";}cout<<endl;LIS(a);printLIS(a);return 0;}

http://www.ahathinking.com/archives/117.html

原创粉丝点击