zoukankan      html  css  js  c++  java
  • 【NOIP模拟】Mushroom的序列

    题面

    Mushroom 手中有 n 个数排成一排,现在 Mushroom 想取一个连续的子序列,使得这个子序列满足:最多只改变一个数,使得这个连续的子序列是严格上升子序列,Mushroom 想知道这个序列的最长长度是多少。

    分析

    先开始以为是dp,后来发现忽略了连续这个要求,不过样例给的是 7 2 3 1 5 6,很明显是把1改成4,就会有长度为5的严格上升子序列

    我发现,1的左右都存在长度较长的上升子序列,于是考虑到预处理以每个位置结束和每个位置开始的连续上升子序列长度,O(N)递推

    再枚举修改哪个数字,ans=max{ 以i-1结尾的上升序列长+以i+1开始的上升序列长+1 },前提是a[i+1]-a[i-1]>1

    有特殊情况,比如前后拼接不起来,只能用前面一段或者后面一段

    序列长为1的时候,显然答案为1,长度>1时,最小答案显然是2

    #include<bits/stdc++.h>
    using namespace std;
    #define N 100100
    int n,ans;
    int s[N],a[N],fs[N],fj[N];
    int main()
    {
        scanf("%d",&n);
        for(int i=1;i<=n;i++)
            scanf("%d",&a[i]);
        fs[n]=1;
        for(int i=n-1;i>=1;i--)
            fs[i]=a[i+1]>a[i]?fs[i+1]+1:1;
        fj[1]=1;
        for(int i=2;i<=n;i++)
            fj[i]=a[i-1]<a[i]?fj[i-1]+1:1;
        ans=min(n,2);
        for(int i=1;i<=n;i++)
            if(a[i+1]-a[i-1]>1)
                ans=max(ans,fs[i+1]+fj[i-1]+1);
        for(int i=1;i<=n;i++)
        {
            ans=max(ans,min(n,fs[i]+1));
            ans=max(ans,min(n,fj[i]+1));
        }    
        printf("%d",ans);
        return 0;
    }
    “Make my parents proud,and impress the girl I like.”
  • 相关阅读:
    计算机网络原理笔记 第一章 概述
    数据结构与算法入门C语言(三)线性结构-离散存储[链表]
    数据结构与算法入门C语言 (二) 线性结构-连续存储[线性表(数组)]
    数据结构与算法入门C语言 (一) 概述
    先画一个圈
    appium 简介和相关名称说明
    appium+python 自动化环境安装
    JDK 1.8 安装
    python安装
    python中的 join()函数
  • 原文地址:https://www.cnblogs.com/NSD-email0820/p/9549243.html
Copyright © 2011-2022 走看看