AcWing 1014. 登山
考察:线性dp
题目本质:求最长上升子序列+下降子序列
易错:
这种题一般都要求下降子序列
j>=i,避免 100 100 100这种数据
也可以用朴素法求,但是要预处理长度数组.
1 #include <iostream> 2 #include <cstring> 3 #include <algorithm> 4 #include <cstdio> 5 using namespace std; 6 const int N = 1010; 7 int h[N],f[N],len,g[N]; 8 int main() 9 { 10 // freopen("in.txt","r",stdin); 11 int n,ans = 0; 12 scanf("%d",&n); 13 for(int i=1;i<=n;i++) scanf("%d",&h[i]); 14 for(int i=1;i<=n;i++) 15 { 16 int low = 0,high = len,len2 = 0; 17 while(low<high) 18 { 19 int mid = low+high+1>>1; 20 if(f[mid]<h[i]) low = mid; 21 else high = mid-1; 22 } 23 f[low+1] = h[i]; 24 len = max(len,high+1); 25 memset(g,0,sizeof g); 26 for(int j=n;j>=i;j--) 27 { 28 int l = 0,r = len2; 29 while(l<r) 30 { 31 int mid = l+r+1>>1; 32 if(g[mid]<h[j]) l = mid; 33 else r = mid-1; 34 } 35 g[l+1] = h[j]; 36 len2 = max(r+1,len2); 37 } 38 if(g[len2]==h[i]) ans = max(len+len2-1,ans); 39 else ans = max(len+len2,ans); 40 } 41 printf("%d\n",ans); 42 return 0; 43 }