求一个数组的最长递减子序列 比如{9,4,3,2,5,4,3,2}的最长递减子序列为{9,5,4,3,2}
------------------------------------------------------
http://blog.csdn.net/wumuzi520/article/details/7378306
这题参见上面这篇博客的动态规划的方法,可以迅速解出,
同时也可以利用回溯遍历出符合的答案,这里需要一个记忆变量
http://www.cnblogs.com/GoAhead/archive/2012/05/30/2525978.html
下面分别简单介绍下:
方法一:动态规划
主要是得出递推关系式
我们每考虑下一个元素,是希望这个元素能够紧跟比他大的元素之后,这样序列能够达到最长
所以有如下关系
f(n) = maxf(i)+1 if a[n]>a[i] i<n
所以我们需要另外一个数组记录这个次数
而如何知道它相连的上一个元素呢?这里还需要再借助一个数组记录这个i
下面给出代码,我这里输出反了,这个大家稍作修改即可
void FindLongestDSCArray2(int *arr, int n){ int *mark = new int[n]; int *link = new int[n]; int i = 0; for(i=0;i<n;i++){ mark[i] = 0; link[i] = -1; } //link[0] = 1; int j = 0, maxMark = 0; for(i=0;i<n;i++){ maxMark = 0; for(j=0;j<i;j++){ if(arr[j]>arr[i]){ if(maxMark<mark[j]){ maxMark = mark[j]; link[i] = j; } } } mark[i] = maxMark+1; } //Print() int node = 0; maxMark = 0; for(i=0;i<n;i++){ if(mark[i]>maxMark) node = i; } while(node != -1){ cout<<arr[node]<<" "; node = link[node]; } }
8 9 4 3 2 5 4 3 2 2 3 4 5 9
#include <iostream> using namespace std; void FindLongestDSCArray(int* arr, int n, int idx1, int* ans, int idx2); void FindLongestDSCArray2(int *arr, int n); int maxNum = 0; int res[20]; int main() { //Input() int input; int n; cin>>n; int *arr = new int[n]; int i = 0; for(i=0;i<n;i++) cin>>arr[i]; //FindLongestDSCArray int ans[20]; int idx1=0,idx2=0; ans[idx2++] = arr[idx1++]; FindLongestDSCArray(arr, n, idx1, ans, idx2); //FindLongestDSCArray2(arr,n); //Print() for(i=0;i<maxNum;i++) cout<<res[i]<<" "; cout<<endl; return 0; } void FindLongestDSCArray(int* arr, int n, int idx1, int* ans, int idx2){ if(idx1 >= n){ if(idx2>maxNum){ maxNum = idx2; int i = 0; for(i=0;i<idx2;i++) res[i] = ans[i]; } return; } if(arr[idx1]< ans[idx2-1]){ ans[idx2] = arr[idx1]; FindLongestDSCArray(arr, n, idx1+1, ans, idx2+1); } else if(idx2-1>=0 && arr[idx1] == ans[idx2-1]) FindLongestDSCArray(arr, n, idx1+1, ans, idx2); else if(idx2-1>=0 && arr[idx1] > ans[idx2-1]){ //跳过 FindLongestDSCArray(arr, n, idx1+1, ans, idx2); //回溯 while(idx2-1>=0 && ans[idx2-1]<=arr[idx1]) idx2--; ans[idx2] = arr[idx1]; FindLongestDSCArray(arr,n,idx1+1,ans,idx2+1); } }
10 9 4 6 3 2 5 1 3 2 1 9 6 5 3 2 1