首页 > 其他分享 >洛谷-P9147 题解

洛谷-P9147 题解

时间:2023-03-15 21:36:27浏览次数:63  
标签:en 洛谷 题解 P9147 枚举 序列 mathcal 上升 单调

正文

最坏时间复杂度:\(\mathcal{O}(n)\)

真不愧是签到题,差点没签上。。。

我相信题意各位肯定很理解了,非常简单,但如何解决就是个问题。

首先考虑朴素解法,建立一个求最长连续子序列的函数 \(F\),如果用双指针的话,可以优化到 \(\mathcal{O}(n)\);然后是枚举每个 \(a_i\),又是一个 \(\mathcal{O}(n)\);易发现,每次枚举 \(a_i\) 更改,我们不需要一个一个数字枚举,只需要枚举三次就行,\(a_i\) 前后的两个数字会构成三个范围,只要分别考虑将 \(a_i\) 修改成这三个范围之内的数即可。

总计 \(\mathcal{O}(n^2)\)。

如何优化呢?

注:以后所提及的单调上升子序列皆为最优。

可以发现,我们并不需要每个枚举。假设一个数处于一个单调上升序列中,把它修改了反而会破坏序列的单调性。因此我们只需枚举每个单调上升子序列首末端,来判断它是否可以和在它前面或后面的单调上升子序列合并组成一个更长的单调上升子序列。

我们预处理 \(l_i\),\(st_i\),\(en_i\),分别代表第 \(i\) 个单调上升子序列的长度、开端位置、末端位置。

假设每个单调上升子序列无法相互合并,那最好的方法就是把最长的单调上升子序列首端或末端更改,让这个最长的单调上升子序列的长度再加一。

即把答案设为 \(\max l_i+1\).

考虑合并,见下,以后设 \(S_i\) 表示原序列第 \(i\) 个数。

1 3 2 6 7。本例中有 2 个单调上升子序列,我们把第 2 个单调上升子序列的开头修改成 4(或者其它)即可。我们可得知:若 \(S_{st_i+1}-S_{en_{(i-1)}}>1\),考虑合并。

当然,不要忘考虑这样的情况:1 4 3 5 7,把第 1 个单调上升子序列的末尾修改成 2 即可,即:若 \(S_{st_i}-S_{en_{(i-1)}-1}>1\),考虑合并。

大体完毕,但,还有特判!!!若 \(S\) 只有一个单调上升子序列,那就输出它的长度,因为它已经是最长了。

总计 \(\mathcal{O}(n)\)。

#include<iostream>
using namespace std;
const int N=1e6+15;
struct P{int l,st,en;}s[N];
int a[N],n,ln,t,mx,cnt,ans;
int main(){
  ios::sync_with_stdio(0),cin.tie(0);
  cin>>n,t=1;
  for(int i=1;i<=n;i++){
    cin>>a[i];
    if(mx<a[i]) ln++,mx=a[i];
    else s[++cnt].st=t,s[cnt].en=i-1,s[cnt].l=ln,
        ln=1,mx=a[i],t=i;
  }
  if(s[cnt].en!=n) s[++cnt].st=t,s[cnt].en=n,s[cnt].l=ln;
  if(cnt==1) cout<<n,exit(0);
  for(int i=1;i<=cnt;i++) ans=max(ans,s[i].l+1);
  for(int i=2;i<=cnt;i++)
    if(a[s[i].st+1]-a[s[i-1].en]>1||a[s[i].st]-a[s[i-1].en-1]>1)
      ans=max(ans,s[i].l+s[i-1].l);
  cout<<ans;
}

完结!!

后附

日志

v1.0 on 2023.03.15: 发布

标签:en,洛谷,题解,P9147,枚举,序列,mathcal,上升,单调
From: https://www.cnblogs.com/wanguan/p/17220136.html

相关文章

  • 【题解】P6667 [清华集训2016] 如何优雅地求和
    orzfjy666orzfjy666orzfjy666神·fjy666·拉普拉斯·爱因斯坦大帝于5min内爆切了此题,膜拜!思路斯特林数。注意到\(f(k)\)是多项式而式子中含有组合数,于......
  • 公众号前端访问后台500 疑难问题解决
     后台日志联调,发现前端根本无法进入后台方法中去经过仔细对比发现referrer请求过长在主设置页面增加<metaname="referrer"content="origin">配置问题解决 ......
  • 阿里一面:15道网络安全真题解析,你能答对几道?
    前言网络安全是一个广阔的领域,面试过程中可能会提出各种各样的问题。招聘人员主要关注技术方面以及工具和技术知识,以确保框架安全。 以下是在网络安全领域寻求工作时可能......
  • 2023.3.14 状压 dp 模拟赛题解
    好强啊。不说是谁了,都好强啊呜呜呜。   首先T1的一个优化luoguP1842奶牛玩杂技,需要一个贪心排序来优化序列顺序。关于贪心排序:像这样有两种及以上性质的序列,......
  • 【洛谷】P2414 [NOI2011] 阿狸的打字机(AC自动机+离线询问)
    原题链接题意给定\(n\)个字符串,\(m\)次询问一个字符串\(x\)在另一个字符串\(y\)的出现次数。\(1\leqn,m\leq10^5\)。思路要解决多个字符串的问题,不难想到......
  • 2020年河南省CCPC 题解
    2020年河南省CCPC题解ProblemA.班委竞选设ax为第x类班干部最大票数。从小到大枚举学号i,若新x>ax则更新ax并且记录i为ansx的答案voidsolve(){intn=re......
  • P5200 [USACO19JAN]Sleepy Cow Sorting G 题解
    前言:教练要求写的,于是过来补发题解。题目传送门分析容易发现后缀如果是上升的那么就不用动,让前面的通过移动插进来就可以了,第一个答案就是\(n\)减去最长上升后缀的长......
  • P4387 洛谷做题笔记 2023313
    P4387洛谷做题笔记2023/3/13这道题的关键点在于,在入栈的同时可以完成出栈操作,这就需要在每一次压入时检测是否出栈。这道题还有一个易错点,就是在每一次询问之后,还必须......
  • CF1788D Moving Dots 题解
    可能更好的阅读体验题目传送门题目翻译题目解析考虑怎样才能产生贡献,显然对于留下的相邻的\(l,r\),需要让\(l\)向右,\(r\)向左即可产生\(1\)的贡献。接下来就是考......
  • [整理]NOIP2021 题解
    T1秒了,直接写一个线性筛一样的东西即可。constintN=10000010;intT,x;boolok[N];intnxt[N];ilvoidInit(){for(inti=1;i<N;i++){if(ok[i])continue;......