题目大意:从左到右游览,从低往高走,再从高往低走(不能走两个海拔一样的),求最多能经过的点的数目
注意两点:
1、不能从头开始找逆序列
2、注意指针类型会识别为long int,必须强制转换
AC1:
#include<iostream> #include<algorithm> #include<string.h> using namespace std; int a[1001],lmax[1001],rmax[1001]; int main() { int n,i,ans,*j,s[1001],t; cin>>n; for (i=1;i<=n;i++) cin>>a[i]; int top=0; lmax[1]=1; memset(s,0,sizeof(s)); s[++top]=a[1]; for (i=2;i<=n;i++) { if (a[i]>s[top]) { s[++top]=a[i]; lmax[i]=std::max(lmax[i-1],top); } else { j=lower_bound(s+1,s+top,a[i]); *j=a[i]; t=j-s;//注意指针类型会识别为long int!,必须强制转换 lmax[i]=std::max(lmax[i-1],t); } } rmax[n]=1;//rmax[i]代表从n开始以i结尾的最大上升子序列长度 top=0; memset(s,0,sizeof(s)); s[++top]=a[n]; for (i=n-1;i>=1;i--)//注意必须倒着找,不可以从头找降序 { if (a[i]>s[top]) { s[++top]=a[i]; rmax[i]=max(rmax[i+1],top); } else { j=lower_bound(s+1,s+top,a[i]); *j=a[i]; t=j-s; rmax[i]=max(rmax[i+1],t); } } ans=lmax[1]+rmax[2]; for (i=2;i<=n-1;i++) ans=max(ans,lmax[i]+rmax[i+1]); cout<<ans<<endl; return 0; }
AC2:
#include<iostream> #include<algorithm> #include<string.h> using namespace std; int a[1001],lmax[1001],rmax[1001]; int main() { int n,i,ans,*j,s[1001]; cin>>n; for (i=1;i<=n;i++) cin>>a[i]; int top=0; lmax[1]=1; memset(s,0,sizeof(s)); s[++top]=a[1]; for (i=2;i<=n;i++) { if (a[i]>s[top]) { s[++top]=a[i]; lmax[i]=top; } else { j=lower_bound(s+1,s+top,a[i]); *j=a[i]; if (lmax[i-1]>(j-s)) lmax[i]=lmax[i+1]; else lmax[i]=j-s; } } rmax[n]=1;//rmax[i]代表从n开始以i结尾的最大上升子序列长度 top=0; memset(s,0,sizeof(s)); s[++top]=a[n]; for (i=n-1;i>=1;i--)//注意必须倒着找,不可以从头找降序 { if (a[i]>s[top]) { s[++top]=a[i]; rmax[i]=top; } else { j=lower_bound(s+1,s+top,a[i]); *j=a[i]; if (rmax[i+1]>(j-s)) rmax[i]=rmax[i+1]; else rmax[i]=j-s; } } ans=lmax[1]+rmax[2]; for (i=2;i<=n-1;i++) if ((lmax[i]+rmax[i+1])>ans) ans=lmax[i]+rmax[i+1]; cout<<ans<<endl; return 0; }