最长递增子序列
2011-04-13 21:24
295 查看
方法一,转为求公共子序列
先对原序列进行排序
然后用对原序列和新序列求其最长公共子序列
所得即原序列的最长非递减子序列
注意,由于所求出来的是最长非递减子序列,所以可能和所要求的不一样,慎用
而且下面所示的代码用的是递归的方法来实现的,时间复杂度和空间复杂度都是O(2^N),真要实现的时候最好采用动态归化+滚动数组的方法
实现代码:
方法二:
方法二就是使用动态归化的方法
设L[i]为以第i个元素结尾的最长递增子序列的长度
最后在所有L[i]中取MAX即为所求
方法三:
方法三和方法二类似,也是使用动态归化的方法
但不同之处是,使用L[i]表示,前i个元素中的最长递增子序列的长度
而且使用labels[i].pos表示,由i个元素组成的最长递增子序列的最后一个元素的位置,而且是所有最后一个元素中最小的一个
这样,其实会导致 i < j的时候 array[ labels[i].pos ] < array [ labels[j].pos ],即array[labels[i].pos]是一个单调递增函数
所以可以使用二分查找的方法,来找到第一个小于当前元素array[i]的array[ labels[i].pos ]的最大的i的位置
先对原序列进行排序
然后用对原序列和新序列求其最长公共子序列
所得即原序列的最长非递减子序列
注意,由于所求出来的是最长非递减子序列,所以可能和所要求的不一样,慎用
而且下面所示的代码用的是递归的方法来实现的,时间复杂度和空间复杂度都是O(2^N),真要实现的时候最好采用动态归化+滚动数组的方法
实现代码:
#include <iostream> #include <vector> #include <algorithm> using namespace std; template<typename InIt> size_t LCS( InIt _First1, InIt _Last1, InIt _First2, InIt _Last2 ) { if( _First1 == _Last1 || _First2 == _Last2 ) { return 0; } if( *_First1 == *_First2 ) { return 1 + LCS( _First1 + 1, _Last1, _First2 + 1, _Last2 ); } else { return max( LCS( _First1, _Last1, _First2 + 1, _Last2 ), LCS( _First1 + 1, _Last1, _First2, _Last2 ) ); } } int main() { int n = 0; vector<int> array; while( (cin >> n) && ( n != 0 ) ) array.push_back( n ); size_t m = 0; cin >> m; vector<int> arraySorted( array.begin(), array.end() ); sort( arraySorted.begin(), arraySorted.end() ); cout << LCS( array.begin(), array.end(), arraySorted.begin(), arraySorted.end() ) << endl; return 0; }
方法二:
方法二就是使用动态归化的方法
设L[i]为以第i个元素结尾的最长递增子序列的长度
最后在所有L[i]中取MAX即为所求
template< typename T > int LIS( T* array, int count ) { if( count == 0 ) return 0; vector<int> L( count, 1 ); for( int i = 1; i < count; i++ ) { for( int j = 0; j < i; j++ ) { if( array[i] > array[j] && L[j] + 1 > L[i] ) { L[i] = L[j] + 1; } } } int maxL = 0; for( int i = 0; i < count; i++ ) { if( maxL < L[i] ) maxL = L[i]; } return maxL; }
方法三:
方法三和方法二类似,也是使用动态归化的方法
但不同之处是,使用L[i]表示,前i个元素中的最长递增子序列的长度
而且使用labels[i].pos表示,由i个元素组成的最长递增子序列的最后一个元素的位置,而且是所有最后一个元素中最小的一个
这样,其实会导致 i < j的时候 array[ labels[i].pos ] < array [ labels[j].pos ],即array[labels[i].pos]是一个单调递增函数
所以可以使用二分查找的方法,来找到第一个小于当前元素array[i]的array[ labels[i].pos ]的最大的i的位置
#include <iostream> #include <iterator> #include <vector> #include <algorithm> using namespace std; template<typename T> struct Program { static vector<T> array; static vector<int> parent; struct Label { int pos; Label(): pos( -1 ) {} Label( int _pos ): pos( _pos ) {} bool operator <( const Label& l ) const { if( pos == -1 && l.pos == -1 ) return false; else if( pos == -1 ) return true; else if( l.pos == -1 ) return false; else return array[pos] < array[l.pos]; } }; void LIS( size_t m = 0 ) { if( array.empty() ) return; vector<size_t> L( array.size(), 1 ); vector<Label> labels( array.size() + 1 ); labels[1].pos = 0; size_t maxL = 1; for( size_t i = 1; i < array.size(); i++ ) { typename vector<Label>::const_iterator it = lower_bound( labels.begin(), labels.begin() + maxL + 1, Label( i ) ); int j = it - labels.begin() - 1; L[i] = j + 1; if( maxL < L[i] ) { maxL = L[i]; labels[maxL].pos = i; parent[i] = labels[j].pos; } else if( array[i] < array[labels[j + 1].pos] ) { labels[j + 1].pos = i; parent[i] = labels[j].pos; } } vector<T> tracks; int p = labels[maxL].pos; while( p != -1 ) { tracks.push_back( array[p] ); p = parent[p]; } reverse_copy( tracks.begin(), tracks.end(), ostream_iterator<T>( cout, " " ) ); cout << endl; } }; template<typename T> vector<T> Program<T>::array; template<typename T> vector<int> Program<T>::parent; int main() { Program<int> p; int n = 0; while( (cin >> n) && ( n != 0 ) ) { p.array.push_back( n ); p.parent.push_back( -1 ); } p.LIS(); return 0; }
相关文章推荐
- B - 最长递增子序列
- hdu1950 Bridging signals(最长递增子序列二分)
- 最长公共子串 最长公共子序列 最长递增子序列
- 【codevs1906】最长递增子序列问题 最大流
- 九度OJ 1131 合唱队形 -- 动态规划(最长递增子序列)
- AOJ-AHU-OJ-189 最长递增子序列(模拟+二分查找)
- 最长递增子序列
- 最长递增子序列
- SGU 199 Beautiful People 二维最长递增子序列
- 动态规划系列之最长递增子序列问题解答
- hdu 1160(最长递增子序列+输出)
- 最长递增子序列
- 算法导论之最长递增子序列
- 51nod 最长递增子序列
- 编程之美--求数组中最长递增子序列
- pku 1836 Alignment(最长递增子序列)
- ZOJ 2136(最长递增子序列)
- 最长递增子序列
- 最长递增子序列——pku2533
- poj 2533 Longest Ordered Subsequence 最长递增子序列