题意

给出一个序列,允许删除一个元素,并将任意元素的值修改为任意整数,问最少修改多少个元素使得序列变成严格单调递增的序列?


题解

这道题目很具有启发性:
不考虑删除元素,原数列各个数值减去他们下标得到一个新的序列,那么新的序列的最长不减序列就是不需要修改的元素个数len,需要修改的元素个数就是n-len即可。

这道题也是这么做的,我们枚举要删除的元素下标为kkk,并且得到以元素k−1" role="presentation" style="position: relative;">k−1k−1k-1为结尾的最长不减序列的长度len1len1len_1,以及得到以元素iii为开始的最长不减序列的长度len2" role="presentation" style="position: relative;">len2len2len_2(要求a[i]+1>=a[k−1]a[i]+1>=a[k−1]a[i]+1 >= a[k-1],因为这样才能将两部分拼接起来),那么这就是删除元素kkk时候得到的最多不需修改的元素的数量,枚举k" role="presentation" style="position: relative;">kkk取最大值即可。

怎样维护以a[i]a[i]a[i]结尾的最长不减序列的长度和以a[i]a[i]a[i]开头的最长不减序列的长度呢?

  • 思路就是dp +(可持久化/动态开点)线段树。
  • dp[a[i]]dp[a[i]]dp[a[i]]表示以a[i]结尾的不减序列的最长长度,那么dp[a[i]]=max(dp[1],dp[2],...,dp[a[i]])+1dp[a[i]]=max(dp[1],dp[2],...,dp[a[i]])+1dp[a[i]] = max(dp[1],dp[2],...,dp[a[i]])+1
  • 线段树的动态开点功能使得不需要离散化。

代码

#include <iostream>
#include <cstring>
#include <cstdio>
#include <algorithm>
#include <cstring>
using namespace std;
const int MAXN = 400008;
struct segtree{int root[MAXN];int val[MAXN * 20];int lson[MAXN * 20];int rson[MAXN * 20];int index;int n;void init(int N){n = N;index = 0;memset(val,0,sizeof(root));memset(val,0,sizeof(val));memset(lson,0,sizeof(lson));memset(rson,0,sizeof(rson));}void insert(int num,int& rt,int l,int r,int v){int nrt = ++index;lson[nrt] = lson[rt];rson[nrt] = rson[rt];val[nrt] = val[rt];rt = nrt;if(l == r) {val[rt] = v;return ;}int mid = (l + r) / 2;if(num <= mid) insert(num,lson[rt],l,mid,v);else insert(num,rson[rt],mid+1,r,v);val[rt] = max(val[lson[rt]],val[rson[rt]]);}int _query(int rt,int l,int r,int ul,int ur){if(r < ul || l > ur) return 0;if(ul <= l && r <= ur) return val[rt];int mid = (l + r) / 2;int a = _query(lson[rt],l,mid,ul,ur);int b = _query(rson[rt],mid+1,r,ul,ur);return max(a,b);}void putone(int i,int pos,int num){root[i] = root[i-1];insert(pos,root[i],1,n,num);}
}seg,segp;
const int inf = 1e9+MAXN;
int n;
int a[MAXN],dp[MAXN];
int main(){seg.init(inf);segp.init(inf);cin>>n;for(int i = 1;i <= n;++i){scanf("%d",&a[i]);a[i] = a[i]-i+MAXN;}int ans = 0;for(int i = n;i >= 1;--i){int mxlen = seg._query(seg.root[n-i],1,inf,a[i],inf);seg.putone(n-i+1,a[i],mxlen+1);ans = max(ans,mxlen+1);//cout<<i<<':'<<mxlen<<endl;}for(int i = 1;i <= n;++i){int mxlen = segp._query(segp.root[i-1],1,inf,1,a[i]);segp.putone(i,a[i],mxlen+1);ans = max(ans,mxlen+1);//cout<<i<<':'<<mxlen<<endl;}for(int i = 2;i < n;++i){int len1 = segp._query(segp.root[i],1,inf,a[i-1],a[i-1]);int len2 = seg._query(seg.root[n-i],1,inf,a[i-1]-1,inf);ans = max(ans,len1+len2);}cout<<max(0,n-ans-1)<<endl;return 0;
}

codeforces G - Almost Increasing Array 动态规划、动态开点线段树相关推荐

  1. codeforces 915E - Physical Education Lessons 动态开点线段树

    题意: 最大$10^9$的区间, $3*10^5$次区间修改,每次操作后求整个区间的和 题解: 裸的动态开点线段树,计算清楚数据范围是关键... 经过尝试 $2*10^7$会$MLE$ $10^7$会 ...

  2. 【线段树合并】解题报告:luogu P4556雨天的尾巴 (树上对点差分 + 动态开点 + 线段树合并)线段树合并模板离线/在线详解

    题目链接:雨天的尾巴 本题本身是一个非常简单的一道树上差分的模板题,但是由于变态的数据范围,我们直接用数组是存不下的(本来使用一颗普通的线段树直接维护最大值即可.但是本题的空间只有128MB,直接按照 ...

  3. 洛谷P3960 列队(动态开节点线段树)

    题意 题目链接 Sol 看不懂splay..,看不懂树状数组... 只会暴力动态开节点线段树 观察之后不难发现,我们对于行和列需要支持的操作都是相同的:找到第\(k\)大的元素并删除,在末尾插入一个元 ...

  4. 动态开点线段树(多棵线段树)的内存分配与回收

    前言 线段树,是一个很好用的能支持O(logn)区间操作的数据结构,随着做一些稍微烦一点的题,有时候会发现有些情况要开一个数组的线段树,更有甚者要树套树,而在很多情况下线段树就不能把所有点都开满了(否 ...

  5. CF1045G AI robots(动态开点线段树)

    题意 火星上有$N$个机器人排成一行,第$i$个机器人的位置为$x_{i}$,视野为$r_{i}$,智商为$q_{i}$.我们认为第$i$个机器人可以看到的位置是$[x_{i}-r_{i},x_{i} ...

  6. NOIP2017 列队——动态开点线段树

    Description: Sylvia 是一个热爱学习的女♂孩子. 前段时间,Sylvia 参加了学校的军训.众所周知,军训的时候需要站方阵. Sylvia 所在的方阵中有n×m名学生,方阵的行数为  ...

  7. HDU 6681 Rikka with Cake(扫描线、动态开点线段树)

    http://acm.hdu.edu.cn/showproblem.php?pid=6681 题意 在矩形区域内有k条射线,问这些射线将矩形分成了多少区域 题解 容易发现答案为所有射线交点个数+1. ...

  8. 洛谷P3120 [USACO15FEB]牛跳房子(动态开节点线段树)

    题意 题目链接 Sol \(f[i][j]\)表示前\(i\)行\(j\)列的贡献,转移的时候枚举从哪里转移而来,复杂度\(O(n^4)\) 然后考虑每一行的贡献,动态开节点线段树维护一下每种颜色的答 ...

  9. CodeForces - 960F[动态开点线段树优化dp]详解

    题意:给一张有向图,每条边有边权与编号,求一条最长的路径,这条路径的边权与编号都是递增的.(编号指输入顺序) 首先我们回忆一下普通得LIS得做法:就是dp[i]以第i个结尾得最长上升子序列的长度,那么 ...

最新文章

  1. Oracle安装——虚拟机搭建图解
  2. CSS魔法堂:你一定误解过的Normal flow
  3. vue 实现数据滚动显示_vue 滚动加载数据
  4. [css] height和line-height的区别是什么呢?
  5. linux中的定时器检测按键,STM32单片机利用定时器实现按键采集
  6. idou老师教你学Istio 04:Istio性能及扩展性介绍
  7. 前端大牛or架构师应该具备这些
  8. linux修改yum本地源的方法
  9. SPICE电路仿真软件介绍
  10. lena图像,直方图均衡
  11. 超简单!用 Python 为图片和 PDF 去掉水印
  12. 雄迈网络摄像头RTSP直播
  13. uboot利用uEnv.txt文件实现灵活功能(加载PL侧bit,修改uenvcmd,配置bootargs,配置bootm,配置bootz)
  14. MAC Mail签名添加图片,不显示为附件操作
  15. RuoYi-Vue简介
  16. 深蓝学院激光slam 理论与实践 第三章激光雷达去畸变 作业习题
  17. 人工智能,机器学习,深度学习(笔记)
  18. 2013年字库产业感悟及资料书单
  19. js后代选择器_jQuery后代选择器用法实例
  20. Python批量对DJ歌曲进行下载,配合电子木鱼更佳

热门文章

  1. java点击关闭弹出窗口_java – JPopupMenu在子弹出窗口打开时关闭
  2. 吴恩达DeepLearningCourse1-神经网络和深度学习
  3. 软件构造学习笔记-第十三周
  4. 不同路径 II-dp
  5. [蓝桥杯2019初赛]完全二叉树的权值-完全二叉树的性质
  6. C++to_string应用举例
  7. C++map容器-大小和互换
  8. linux下I2C驱动发送IO时序,I2C驱动情景分析——怎样控制I2C时序
  9. TCP提供可靠传输的工作原理和实现过程
  10. synchronized的实现原理