登山

  题目描述:

五一到了,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 } 

 

因为本期题目与上一期基本类似,所以写的不是特别详细,如不懂,那么请看上期  《 重 启 系 统 》

 

posted @ 2022-03-05 23:52  XDFZ武斌  阅读(137)  评论(0)    收藏  举报