登山
题目描述:
五一到了,ACM队组织大家去登山观光,队员们发现山上一共有N个景点,现在告诉你这N个景点的海拔。队员们决定按照顺序来浏览这些景点,即每次所浏览景点的下标都要大于前一个浏览景点的下标。
同时队员们还有另一个登山习惯,就是不连续浏览海拔相同的两个景点,并且一旦开始下山,就不再向上走了。
队员们希望在满足上面条件的同时,尽可能多的浏览景点,你能帮他们找出最多可能浏览的景点
输入:
Line 1: N (2 <= N <= 1000) 景点数。
Line 2: N个整数,每个景点的海拔。
输出:
最多能浏览的景点数。
样例输入:
8 186 186 150 200 160 130 197 220
样例输出:
4
思路:
此题与上期的 重启系统 基本上一样,不过它多了两个限定条件:
1 . 不连续浏览海拔相同的两个景点
2 . 一旦开始下山,就不再向上走了
第二个条件的大致意思指,一旦现在的这个山峰的高度比上一个山峰的高度小,那么接下来山峰的高度就必须是递减的了。
但是这道题也有个好处,就是不用修改dp的意义(上一期就修改了一点dp的意义,多加了一个处理),常规的LIS就能做出。
同样,从左往右dp,再从右往左dp,最后取同下标相加的最大值即可!!!
代码↓
1 #include <bits/stdc++.h> 2 using namespace std; 3 #define XINF INT_MIN 4 5 int dp1[1005],dp2[1005],a[1005]; 6 int n; 7 8 int main(){ 9 scanf("%d",&n); 10 for (int i = 1;i <= n;i++){ 11 scanf("%d",&a[i]); 12 dp1[i] = 1; 13 dp2[i] = 1; 14 }//输入以及初始化 15 for (int i = 2;i <= n;i++){ 16 for (int j = 1;j < i;j++){ 17 if(a[i] > a[j]){ 18 dp1[i] = max(dp1[i],dp1[j]+1); 19 } 20 } 21 }//从左往右dp 22 for (int i = n-1;i >= 1;i--){ 23 for (int j = i + 1;j <= n;j++){ 24 if(a[i] > a[j]){ 25 dp2[i] = max(dp2[i],dp2[j]+1); 26 } 27 } 28 }//从右往左dp 29 int ans = XINF;//答案,赋值为负无穷(赋值0也可以,因为dp初始化就为1) 30 for (int i = 1;i <= n;i++){ 31 ans = max(ans,dp1[i] + dp2[i]);//取同下标相加最大值 32 } 33 printf("%d",ans-1);//记得 -1 !!! 34 return 0; 35 }
因为本期题目与上一期基本类似,所以写的不是特别详细,如不懂,那么请看上期 《 重 启 系 统 》
本文来自博客园,作者:XDFZ武斌,转载请注明原文链接:https://www.cnblogs.com/XDFZwb1523/p/15969983.html

浙公网安备 33010602011771号