最长不下降子序列

题目:

设有由n(1≤n≤200))个不相同的整数组成的数列,记为:b(1)、b(2)、……、b(n)b(1)、b(2)、……、b(n)若存在i1<i2<i3<…<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个整数形成的不下降序列,答案可能不唯一,输出一种就可以了。

1.

#include<iostream>
#include<cstdio>
using namespace std;
int n,a[1001],f[1001],p[1001];

void dfs(int i)
{
    if(p[i]>0) dfs(p[i]);
    cout<<a[i]<<" ";
}
int main()
{
    int n,ans;
    cin>>n;
    for(int i=1;i<=n;i++)
    {
        cin>>a[i];        
     } 
    f[1]=1;
    p[1]=0;
    for(int i=2;i<=n;i++)
    {
        f[i]=0;
        for(int j=1;j<i;j++)
        {
            if(a[j]<=a[i]&&f[i]<f[j])
            { 
                 f[i]=f[j];
                 p[i]=j; 
            }    
        }
        f[i]++;
    }
    ans=f[1];
    int k=1;
    for(int i=2;i<=n;i++)
    {
        if(f[i]>ans) 
        {    
        k=i;
        ans=f[i];        
        }
    }
    cout<<"max="<<ans<<endl;
    dfs(k);
    return 0;
     
}

2.优化

#include<iostream>
#include<cstdio>
using namespace std;
int n,a[1001],f[1001];
int cnt;

void dfs(int i)
{
    if(f[i]>0) dfs(f[i]);
    cout<<a[i]<<" ";
}

int main()
{//hello hello~
    int n,k;
    cin>>n;
    for(int i=1;i<=n;i++)
    {
        cin>>a[i];        
     } 
    f[1]=a[1];
    int ans=f[1];
    cnt=1;
    for(int i=2;i<=n;i++)
    {
        int l=1,r=cnt+1;
        f[r]=1e9;
        while(l<r)
        {
            int mid=(l+r)>>1;
            if(f[mid]>=a[i]) r=mid;
            else l=mid+1;
        }
        f[l]=a[i];
        if(l==cnt+1) cnt++;
            if(f[i]>ans) 
        {    
        k=i;
        ans=f[i];        
        }
    }
    cout<<" max="<<cnt<<endl;
    dfs(k);
    return 0;
     
}

 

posted @ 2022-09-25 19:52  为么要取名字  阅读(28)  评论(0编辑  收藏  举报