求一個數組的最長遞減子序列比如{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;
- }