P8776 [蓝桥杯 2022 省 A] 最长不下降子序列 (动态规划)
测试链接:https://www.luogu.com.cn/problem/P8776
P8776 [蓝桥杯 2022 省 A] 最长不下降子序列
题目描述
给定一个长度为 \(N\) 的整数序列:\(A_{1}, A_{2}, \cdots, A_{N}\)。现在你有一次机会,将其中连续的 \(K\) 个数修改成任意一个相同值。请你计算如何修改可以使修改后的数列的最长不下降子序列最长,请输出这个最长的长度。
最长不下降子序列是指序列中的一个子序列,子序列中的每个数不小于在它之前的数。
输入格式
输入第一行包含两个整数 \(N\) 和 \(K\) 。
第二行包含 \(N\) 个整数 \(A_{1}, A_{2}, \cdots, A_{N}\) 。
输出格式
输出一行包含一个整数表示答案。
输入输出样例 #1
输入 #1
5 1
1 4 2 8 5
输出 #1
4
说明/提示
对于 \(20 \%\) 的评测用例, \(1 \leq K \leq N \leq 100\);
对于 \(30 \%\) 的评测用例, \(1 \leq K \leq N \leq 1000\);
对于 \(50 \%\) 的评测用例, \(1 \leq K \leq N \leq 10000\);
对于所有评测用例, \(1 \leq K \leq N \leq 10^{5}, 1 \leq A_{i} \leq 10^{6}\) 。
蓝桥杯 2022 省赛 A 组 G 题。
思路
将数组划分为三份,中间是转化成长度为k的转换区域,左边求最大不下降子序列,且结尾值小于右边区域的第一个数的大小,右边求以第一个数开头的最大不下降子序列
左边正常更新即可,右边区域需要倒序求最大不上升子序列来保证right区域求出正确的最大不下降子序列
题解
#include <bits/stdc++.h>
using namespace std;
const int N=1e5+10;
typedef long long ll;
int t,n;
int k;
int a[N],r[N],endss[N];
int ans;
int f2(int len,int num)
{
int l=0,r=len-1,ans=-1;
while(l<=r)
{
int m = (l+r)/2;
if(endss[m]>num)
{
ans = m;
r = m-1;
}
else l = m+1;
}
return ans;
}
int f1(int len,int num)
{
int l=0,r=len-1,ans=-1;
while(l<=r)
{
int m = (l+r)/2;
if(endss[m]<num)
{
ans = m;
r = m-1;
}
else l = m+1;
}
return ans;
}
void right()
{
int len = 0;
for(int i=n-1;i>=0;i--)
{
int find = f1(len,a[i]);
if(find==-1)
{
endss[len++] = a[i];
r[i] = len;
}
else
{
endss[find]=a[i];
r[i]=find+1;
}
}
}
int compute()
{
right();
int len = 0;
int ans = 0;
for(int i=0,j=k,left;j<n;i++,j++)
{
int find = f2(len,a[j]);
left = find==-1?len:find;
ans = max(ans,left+k+r[j]);
find = f2(len,a[i]);
if(find==-1)endss[len++] = a[i];
else endss[find] = a[i];
}
ans = max(ans,len+k);
return ans;
}
int main()
{
ios::sync_with_stdio(0);
cin.tie(0);
cout.tie(0);
cin>>n>>k;
for(int i=0;i<n;i++)cin>>a[i];
if(k>=n)cout<<n<<endl;
else
{
cout<<compute()<<endl;
}
return 0;
}
P8776 [蓝桥杯 2022 省 A] 最长不下降子序列 (动态规划)的更多相关文章
- HDU 6357.Hills And Valleys-字符串非严格递增子序列(LIS最长非下降子序列)+动态规划(区间翻转l,r找最长非递减子序列),好题哇 (2018 Multi-University Training Contest 5 1008)
6357. Hills And Valleys 自己感觉这是个好题,应该是经典题目,所以半路选手补了这道字符串的动态规划题目. 题意就是给你一个串,翻转任意区间一次,求最长的非下降子序列. 一看题面写 ...
- 【C/C++】最长不下降子序列/动态规划
#include <iostream> #include <vector> using namespace std; int main() { //输入 int tmp; ve ...
- 算法进阶 (LIS变形) 固定长度截取求最长不下降子序列【动态规划】【树状数组】
先学习下LIS最长上升子序列 看了大佬的文章OTZ:最长上升子序列 (LIS) 详解+例题模板 (全),其中包含普通O(n)算法*和以LIS长度及末尾元素成立数组的普通O(nlogn)算法,当然还 ...
- 最长不下降子序列(LIS)
最长上升子序列.最长不下降子序列,解法差不多,就一点等于不等于的差别,我这里说最长不下降子序列的. 有两种解法. 一种是DP,很容易想到,就这样: REP(i,n) { f[i]=; FOR(j,,i ...
- 最长不下降子序列 O(nlogn) || 记忆化搜索
#include<stdio.h> ] , temp[] ; int n , top ; int binary_search (int x) { ; int last = top ; in ...
- tyvj 1049 最长不下降子序列 n^2/nlogn
P1049 最长不下降子序列 时间: 1000ms / 空间: 131072KiB / Java类名: Main 描述 求最长不下降子序列的长度 输入格式 第一行为n,表示n个数第二行n个数 输出格式 ...
- 最长不下降子序列的O(n^2)算法和O(nlogn)算法
一.简单的O(n^2)的算法 很容易想到用动态规划做.设lis[]用于保存第1~i元素元素中最长不下降序列的长度,则lis[i]=max(lis[j])+1,且num[i]>num[j],i&g ...
- 最长不下降子序列//序列dp
最长不下降子序列 时间: 1000ms / 空间: 131072KiB / Java类名: Main 描述 求最长不下降子序列的长度 输入格式 第一行为n,表示n个数第二行n个数 输出格式 最长不下降 ...
- 【tyvj】P1049 最长不下降子序列
时间: 1000ms / 空间: 131072KiB / Java类名: Main 描述 求最长不下降子序列的长度 输入格式 第一行为n,表示n个数 第二行n个数 输出格式 最长不下降子序列的长度 测 ...
- hdu 4604 Deque(最长不下降子序列)
从后向前对已搜点做两遍LIS(最长不下降子序列),分别求出已搜点的最长递增.递减子序列长度.这样一直搜到第一个点,就得到了整个序列的最长递增.递减子序列的长度,即最长递减子序列在前,最长递增子序列在后 ...
随机推荐
- python 读写、创建文件
python中对文件.文件夹(文件操作函数)的操作设计到os模块以及shutil模块 os模块提供了对目录或者文件的新建/删除/查看文件属性,还提供了对文件以及目录的路径操作,比如:绝对路径,父路径等 ...
- Java IO<5>管道流PipedOutputStream PipedInputStream
在java中,PipedOutputStream和PipedInputStream分别是管道输出流和管道输入流.它们的作用是让多线程可以通过管道进行线程间的通讯.在使用管道通信时,必须将PipedOu ...
- Windows11 关闭搜索栏中的Web网页搜索
️ Win11 搜索栏总弹出网页搜索通过注册表彻底关闭 在 Windows 11 系统中,当你通过任务栏中的搜索栏查找内容时,除了显示本地文件.应用和设置外,系统还会自动集成 Bing 搜索结果,展示 ...
- 你了解 Java 的类加载器吗?类加载机制是什么?什么是双亲委派机制?
什么是类加载器,类加载器有哪些? 实现通过类的全限定名获取该类的二进制字节流的代码块叫做类加载器. 主要有一下四种类加载器: 启动类加载器:用来加载 Java 核心类库,无法被 Java 程序直接引用 ...
- 工作流引擎系统-基于橙单(flowable)的系统开发-流程配置举例
什么是工作流引擎(Workflow Engine ) 例如开发一个系统,最关键的部分不是系统的界面(增删改查之类),也不是和数据库之间的交互(读写数据库之类),而是如何根据业务逻辑开发出符合实际需要的 ...
- cf908(div2)题解(补题)
第一次akdiv2,赛后ak怎么不算是ak呢 比赛链接cf908div2 A 这题是个骗人题,整个比赛会停下来就是一个人赢够了回合数,那么在谁这停下来就是谁赢了整个比赛,不用管每回合赢得规则. #in ...
- java基础(逻辑运算、异常)
长路运算 & | 长路与运算会把两边的关系运算结果都计算出来,然后再进行对比 例子:4<3 & 5*3>12 结果是false 短路运算(提高运算效率) && ...
- 前端开发系列120-进阶篇之deepClone
本文讨论数据的拷贝,并给出深拷贝的实现代码. 拷贝即复制( copy | clone ),获取指定数据副本的一种行为,理论上我们可以对任意类型的数据进行拷贝,包括但不限于null.undefined. ...
- Codeforces Round #708 (Div. 2) ABC1C2题解
A. Meximization 第i位优先放等于i-1的,没有的话就后面随便填了. view code #include<iostream> #include<string> ...
- 将id=5以及emp_no=10001的行数据替换成id=5以及emp_no=10005,其他数据保持不变,使用replace实现,直接使用update会报错。
简介 修改数据 update titles_test set emp_no = replace(emp_no, 10001, 10005) where id = 5; update titles_te ...