計蒜客-求陣列的最長遞減子序列
阿新 • • 發佈:2018-12-31
給定一個整數序列,輸出它的最長遞減(注意不是“不遞增”)子序列。
輸入包括兩行,第一行包括一個正整數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;
}