- 总时间限制:
- 5000ms
- 内存限制:
- 131072kB
- 描述
-
五一到了,PKU-ACM队组织大家去登山观光,队员们发现山上一个有N个景点,并且决定按照顺序来浏览这些景点,即每次所浏览景点的编号都要大于前一个浏览景点的编号。同时队员们还有另一个登山习惯,就是不连续浏览海拔相同的两个景点,并且一旦开始下山,就不再向上走了。队员们希望在满足上面条件的同时,尽可能多的浏览景点,你能帮他们找出最多可能浏览的景点数么?
- 输入
-
Line 1: N (2 <= N <= 1000) 景点数
Line 2: N个整数,每个景点的海拔 - 输出
- 最多能浏览的景点数
- 样例输入
-
8 186 186 150 200 160 130 197 220
- 样例输出
-
4
- 来源
第六届北京大学程序设计大赛暨ACM/ICPC选拔赛
有两点,一次上山一次下山
#include<iostream> #include<string.h> #include<algorithm> #define msm(a,b) memset(a,b,sizeof(a)) using namespace std; int dp1[1100],dp2[1100]; int main() { int n; long long tall[1100]; cin>>n; for(int i=1;i<=n;i++){ cin>>tall[i]; dp1[i]=dp2[i]=1; } int res=0; for(int i=n;i>=1;i--){ for(int j=n;j>i;j--){ if(tall[i]>tall[j]){ dp1[i]=max(dp1[j]+1,dp1[i]); } } } for(int i=1;i<=n;i++){ for(int j=1;j<i;j++){ if(tall[i]>tall[j]){ dp2[i]=max(dp2[j]+1,dp2[i]); } } } for(int i=1;i<=n;i++){ res=max(dp1[i]+dp2[i]-1,res); } cout<<res<<endl; return 0; }
首先把每个赋初值为1
然后第一个for循环找出每个点后面有几个可以下
第二个for循环找出每个点前面有几个可以上
然后相加找出最大的即可(注意:连接上山下山的点重复了,即-1)