1. 程式人生 > >最長不下降序列加輸出路徑

最長不下降序列加輸出路徑

1259:【例9.3】求最長不下降序列


時間限制: 1000 ms         記憶體限制: 65536 KB
提交數: 5785     通過數: 1758 

【題目描述】

設有由n(1≤n≤200)n(1≤n≤200)個不相同的整陣列成的數列,記為:b(1)、b(2)、……、b(n)b(1)、b(2)、……、b(n)且b(i)≠b(j)(i≠j)b(i)≠b(j)(i≠j),若存在i1<i2<i3<…<iei1<i2<i3<…<ie且有b(i1)<b(i2)<…<b(ie)b(i1)<b(i2)<…<b(ie)則稱為長度為e的不下降序列。程式要求,當原數列出之後,求出最長的不下降序列。

例如13,7,9,16,38,24,37,18,44,19,21,22,63,15。例中13,16,18,19,21,22,63就是一個長度為7的不下降序列,同時也有7 ,9,16,18,19,21,22,63組成的長度為8的不下降序列。

 

【輸入】

第一行為n,第二行為用空格隔開的n個整數。

【輸出】

第一行為輸出最大個數max(形式見樣例);

第二行為max個整數形成的不下降序列,答案可能不唯一,輸出一種就可以了,本題進行特殊評測。

【輸入樣例】

14
13 7 9 16 38 24 37 18 44 19 21 22 63 15

【輸出樣例】

max=8
7 9 16 18 19 21 22 63

【來源】


No


#include<iostream>
#include<cstring>
#include<algorithm>
#include<cstdio>
using namespace std;
#define maxn 5005
int a[maxn];
int pre[maxn];
int f[maxn];
int ans[maxn];
int main()
{
    int n;
    while(~scanf("%d",&n))
    {
    memset(pre,0,sizeof(pre));
    memset(f,0,sizeof(f));
    memset(ans,0,sizeof(ans));
    for(int i=1;i<=n;i++)
        scanf("%d",&a[i]);
        for(int i=1;i<=n;i++)
            f[i]=1;
            int l,k;
    for(int i=2;i<=n;i++)
    {
        l=0,k=1;
        for(int j=1;j<i;j++)
        {
            if(a[i]>=a[j]&&f[j]>l)
            {
                l=f[j];
                k=j;
            }
        }
        if(l>0)
        {
            pre[i]=k;
            f[i]=l+1;
        }
    }
    k=1;
    int maxm=-1000000;
    for(int i=1;i<=n;i++)
    {if(f[i]>maxm)
    {
        maxm=f[i];
        k=i;
    }

    }
    printf("max=%d\n",maxm);

    int d=0;
    while(k!=0)
    {
        ans[d++]=a[k];;
        k=pre[k];
    }
    for(int i=d-1;i>=1;i--)
        printf("%d ",ans[i]);
        printf("%d\n",ans[0]);

    }
    return 0;
}