这是2006北大举办的ACM的一道题。c++
题意为:给定景点海拔高度,队员们不去游览相同高度的景点,一开始往上爬,一但往下爬就不能再向上爬,求最多能够游览多少个景点。那么咱们能够获得一个结论:以一个最高点为区分,前面的是最大上升子序列,后面的是最大降低子序列。而后咱们就完全把此传化为了LIS问题。咱们开始思考:集合?以峰值为终点的最大子序列长度(一个1-n;一个n~1)。属性?最大值。划分依据与计算?以a[i]结尾的序列a[1],a[2],a[i-1],a[i]里找到a[j]<a[i[,那么状态则能够转化为前面那个数的状态+1,而后与当前进行比较便可。固然当j=0时,dp[i]=1。其次要注意这个反向的时候逆序来求,要再开一个集合。最后枚举峰值点便可。spa
代码code
#include<bits/stdc++.h> #define maxn 1010 using namespace std; int dp1[maxn],dp2[maxn]; int n; int a[maxn]; int main(){ cin>>n; for(int i=1;i<=n;i++){ cin>>a[i]; } for(int i=1;i<=n;i++){ dp1[i]=1; for(int j=1;j<i;j++){ if(a[i]>a[j]){ dp1[i]=max(dp1[i],dp1[j]+1); } } } for(int i=n;i>=1;i--){ dp2[i]=1; for(int j=n;j>i;j--){ if(a[i]>a[j]){ dp2[i]=max(dp2[i],dp2[j]+1); } } } int res=0; for(int i=1;i<=n;i++){ res=max(res,dp1[i]+dp2[i]-1); } cout<<n; return 0; }