链接http://noi.openjudge.cn/ch0206/1996/
描述
五一到了,PKU-ACM队组织大家去登山观光,队员们发现山上一个有N个景点,并且决定按照顺序来浏览这些景点,即每次所浏览景点的编号都要大于前一个浏览景点的编号。同时队员们还有另一个登山习惯,就是不连续浏览海拔相同的两个景点,并且一旦开始下山,就不再向上走了。队员们希望在满足上面条件的同时,尽可能多的浏览景点,你能帮他们找出最多可能浏览的景点数么?
输入Line 1: N (2 <= N <= 1000) 景点数
Line 2: N个整数,每个景点的海拔输出最多能浏览的景点数样例输入
8 186 186 150 200 160 130 197 220
样例输出
4
来源第六届北京大学程序设计大赛暨ACM/ICPC选拔赛
思路对了,其实不难就是两次LIS。刚开始的时候,我思考的问题是以i为结尾的先上升后下降序列的最长长度(笑)这个问题不满足最优子结构。陷入这个误区之后,百思不得其解。不知道为什么,很容易陷入误区中= =
#include<cstdio> #include<cmath> #include<iostream> #include<algorithm> #include<vector> #include<string> #include<map> #include<cstring> #define DEBUG(x) cout << #x << " = " << x << endl using namespace std; const int MAXN=1e3+10; int N; int num[MAXN]; ///从左到右以i为终点的最大景点数 int maxSum1[MAXN]; ///从右到左以i为终点的最大景点数 int maxSum2[MAXN]; int main() { // freopen("in.txt","r",stdin); scanf("%d",&N); for(int i=1;i<=N;i++){ scanf("%d",&num[i]); } for(int i=1;i<=N;i++){ maxSum1[i]=maxSum2[i]=1; } for(int i=2;i<=N;i++){ for(int j=1;j<=i-1;j++){ if(num[i]>num[j])maxSum1[i]=max(maxSum1[i],maxSum1[j]+1); } } for(int i=N-1;i>=1;i--){ for(int j=N;j>=i+1;j--){ if(num[i]>num[j])maxSum2[i]=max(maxSum2[i],maxSum2[j]+1); } } int r=-1; for(int i=1;i<=N;i++){ r=max(r,maxSum1[i]+maxSum2[i]-1); } printf("%d ",r); return 0; }