求一个数组的最长递减子序列比如{9,4,3,2,5,4,3,2}的最长递减子序列为{9,5,4,3,2}
分析:典型的动态规划题目,对每一个数计算由它开始的最大递减子序列的个数,并存放到一张映射表中。例如对数组a[n]有
……
然后利用求得的映射表及最大子序列个数获取原数组中的元素。对于{9,4,3,2,5,4,3,2}我们求得最大子序列个数为nMaxLen=5,表为pTable={5,3,2,1,4,3,2,1}。那么pTable中以此找出nMaxLen,nMaxLen-1,…,1对应的原数组的值即为最大递减子序列。对应的为{9,5,4,3,2}.复杂度为O(n2)
代码如下
- #include <iostream>
- #include <cstring>
- using namespace std;
- int Fun(int aIn[],int pTable[],int nLen)
- {
- int nMaxLen = 0;
- for(int i = nLen-1; i >= 0; --i) {
- int nMax = 0;
- for(int j = i+1; j < nLen; ++j) {
- if(aIn[j] < aIn[i]) {
- nMax = nMax < pTable[j] ? pTable[j] : nMax;
- }
- }
- pTable[i] = 1+nMax;
- nMaxLen = nMaxLen<pTable[i] ? pTable[i] : nMaxLen;
- }
- return nMaxLen;
- }
- void PrintMaxSubsequence(int aIn[], int pTable[], int nMaxLen, int nLen)
- {
- for(int i = 0,j=0; i < nLen; ++i) {
- if(pTable[i] == nMaxLen){
- cout << aIn[i] << " ";
- nMaxLen--;
- }
- }
- cout << endl;
- }
测试代码如下:
- int main()
- {
- int aIn[] = {9,4,3,2,5,4,3,2};
- int nLen = sizeof(aIn)/sizeof(int);
- int* pTable = new int[nLen];
- memset(pTable,0,nLen*sizeof(int));
- int nMaxLen = Fun(aIn,pTable,nLen);
- cout << nMaxLen << endl;
- PrintMaxSubsequence(aIn,pTable,nMaxLen,nLen);
- delete [] pTable;
- return 0;
- }