luogu1970 花匠(dp)
设f1[i]表示以1..i中某个合法序列的长度,而且最后一位是较大的
f2[i]表示以1..i中某个合法序列的长度,而且最后一位是较小的
那么就有$f1[i]=max\{f2[j]+1\},(j<i,h[j]<h[i])$,f2同理
本来想直接建线段树来维护这个最大值的,但是似乎不需要:
对于f1,如果h[i-1]<h[i],那显然从i-1更新过来比较好;但如果h[i-1]>h[i],那其实f[i]=f[i-1],因为这种情况中选i-1一定是比i不亏的,因为i-1更大一点。
f2同理
1 #include<bits/stdc++.h> 2 #define pa pair<int,int> 3 #define ll long long 4 using namespace std; 5 const int maxn=100010; 6 7 inline ll rd(){ 8 ll x=0;char c=getchar();int neg=1; 9 while(c<'0'||c>'9'){if(c=='-') neg=-1;c=getchar();} 10 while(c>='0'&&c<='9') x=x*10+c-'0',c=getchar(); 11 return x*neg; 12 } 13 14 int N,h[maxn]; 15 int f1[maxn],f2[maxn]; 16 17 int main(){ 18 int i,j,k; 19 N=rd(); 20 for(i=1;i<=N;i++) h[i]=rd(); 21 f1[1]=f2[1]=1; 22 for(i=2;i<=N;i++){ 23 if(h[i]>=h[i-1]) f1[i]=f1[i-1]; 24 else f1[i]=f2[i-1]+1; 25 if(h[i]<=h[i-1]) f2[i]=f2[i-1]; 26 else f2[i]=f1[i-1]+1; 27 } 28 printf("%d\n",max(f1[N],f2[N])); 29 return 0; 30 }