1. 程式人生 > >計蒜客-求陣列的最長遞減子序列

計蒜客-求陣列的最長遞減子序列

給定一個整數序列,輸出它的最長遞減(注意不是“不遞增”)子序列。

輸入包括兩行,第一行包括一個正整數N(N<=1000),表示輸入的整數序列的長度。第二行包括用空格分隔開的N個整數,整數範圍區間為[-30000,30000]。

輸出為一行,最長遞減子序列的結果,數字間用空格分隔(測試case中只會有一個最長遞減子序列)。
樣例輸入

8
9 4 3 2 5 4 3 2

樣例輸出

9 5 4 3 2

同上一篇部落格,只不過這是遞減,思想差不多,就是每在一個位置就從前往後遍歷,每一個都判斷,與i構成遞減序列是否比之前儲存的i的數量大,如果是就更新,不過這個要用pre陣列記錄下,遞減序列前一個數的下標。

#include <iostream>
#include <cstdio>
#include <algorithm>
#include <stack>
#include <cstring>
using namespace std;
int num[1005];
int dp[1005];
int pre[1005];
int main(){
    int n,i,j;
    while(scanf("%d",&n)!=EOF){
        memset(dp,1,sizeof(dp));
        memset(pre,-1
,sizeof(pre)); for ( i = 0; i < n; ++i) { scanf("%d",&num[i]); } for ( i = 1; i < n; ++i) { for ( j = 0; j < i; ++j) { if(num[i]<num[j]&&dp[j]+1>dp[i]){ dp[i]=dp[j]+1
; pre[i]=j; } } } int maxlen=0; for ( i = 0; i < n; ++i) { if (maxlen<dp[i]) { maxlen=dp[i]; j=i; } } stack<int> v; while(j!=-1){ v.push(num[j]); j=pre[j]; } printf("%d", v.top()); v.pop(); while(!v.empty()){ printf(" %d", v.top()); v.pop(); } printf("\n"); } return 0; }