创新工场:
而,如果采用递归穷举,则见下面代码
求一个数组的最长递减子序列 比如{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