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; }