九度 題目1262:Sequence Construction puzzles(I)_構造全遞增序列

題目描述:

給定一個整數序列,請問如何去掉最少的元素使得原序列變成一個全遞增的序列。

輸入:

輸入的第一行包括一個整數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
****************************************************************/


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章