最长不下降子序列

DP专题开始了~~~~

用最长不下降子序列开头吧


 

所谓最长不下降子序列,也就是在一个数列中,抽出一些数,这些数满足 后面的数>前面的数,现在希望求最长的这么一个子序列。

通常问题会这样描述:给一个n,表示数列中有n个数。下一行n个数,表示这个数列中数的大小。让我们输出最长不下降子序列。


例子:n=4:1 3 1 2

最长的只能是 1、2

如果搜索:一个数选还是不选,2的指数倍复杂度,螺旋升天,笋干爆炸。

不多逼逼,直接讲朴素的正解:

定义一个数组 F[x],表示x能连接的最长不下降子序列的长度。

然后要推出答案,怎么推呢?

首先还没开始推的时候,每一个的答案都是1,因为包含自己。因此F[X]=1。

注意:F[n]就已经是第n个数的最终答案了,因为第n个数右边已经没有数了。

那么F[n-1]就有几种可能,如果第 n个数大于第n-1个数,F[n-1]=F[n-1]+f[n],反过来就没有操作。

F[n-2],有可能第n个数大于第n-2个数,但是第n-1个数不大于n-2个数,因此需要从第n-2个数右边开始寻找比它大的数,假设这个数是y吧,就要F[n-2]=max(F[n-2],F[y]+1)

所以这么写:

#include<iostream>
#include<cstdio>
using namespace std;
int n;
int maxx;
int a[10001],f[10001];
int main(){
    cin>>n;
    maxx=1;
    for(int i=1;i<=n;i++){
        cin>>a[i];
        f[i]=1;
    }
    for(int i=n-1;i>=1;i--){
        for(int j=i+1;j<=n;j++)
            if(a[i]<a[j])
                f[i]=max(f[j]+1,f[i]);
        maxx=max(f[i],maxx);
    }
    cout<<maxx<<endl;
    return 0;
} 

 

posted @ 2018-07-18 09:15  PIPIXUE  阅读(333)  评论(0编辑  收藏  举报