登山

链接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\n",r);
    return 0;
}

猜你喜欢

转载自www.cnblogs.com/MalcolmMeng/p/9185076.html