- 題目描述:
-
給定一個整數序列,請問如何去掉最少的元素使得原序列變成一個全遞增的序列。
- 輸入:
-
輸入的第一行包括一個整數N(1<=N<=10000)。
接下來的一行是N個滿足題目描述條件的整數。
- 輸出:
-
可能有多組測試數據,對於每組數據,
輸出去掉最少的元素後的全遞增序列。
- 樣例輸入:
-
8 186 186 150 200 160 130 197 220
- 樣例輸出:
-
150 160 197 220
- 提示:
-
如果有多個結果序列滿足條件,輸出相對位置靠前的那個序列。
-
-
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-
明顯用dp,dp[j][i]表示第j個元素在第i個元素之前所能組成的最長遞增子序列。
-
-
仔細思考一下,其實完全不用二維數組,只要將當前第i個元素能組成最長遞增序列的值記錄下來。求第j個元素的最大遞增子序列時,只需將第j個元素和前j-1個元素依次比較,如果第j個元素大於第k個元素並且現在第j個元素此時最長遞增子序列小於第K個元素的最長遞增子序列長度加1,就更新第j個,元素所能組成的最長遞增子序列的長度。
-
-
用一列數組存儲每個元素最長遞增子序列的前一個元素的位置,所以代碼如下:
-
-
-
#include<iostream> #include<stdio.h> #include<algorithm> #include<string.h> using namespace std; int v[10001]; int qian[10001]; int s[10001]; int pt[10001]; int n; int main() { int j,i; while(cin>>n&&n) { for(j=0;j<n;j++) { scanf("%d",s+j); v[j]=1; qian[j]=j; } for(j=1;j<n;j++) for(i=0;i<j;i++) if(s[j]>s[i]&&v[i]+1>v[j]) { v[j]=v[i]+1; qian[j]=i; } int tp=0,ma=1; for(j=1;j<n;j++) if(v[j]>ma) { ma=v[j]; tp=j; } i=0; while(qian[tp]!=tp) { pt[i]=s[tp]; i++; tp=qian[tp]; } pt[i]=s[tp]; for(j=i;j>0;j--) printf("%d ",pt[j]); printf("%d\n",pt[0]); } return 0; } /************************************************************** Problem: 1262 User: 午夜小白龍 Language: C++ Result: Accepted Time:20 ms Memory:1676 kb ****************************************************************/