Luogu P2501 [HAOI2006]数字序列
题目
首先把\(a\)改成严格单调上升等于把\(a_i-i\)改成单调不降。
那么第一问可以直接做LIS,答案就是\(n-\)LIS的长度。
同时我们记录一下序列中每个位置结尾的LIS长度。
第二问我们考虑这样一个事实:
对于LIS中相邻的两个数\(a_i,a_j\),这两个数中间的数一定要么\(<a_i\)要么\(>a_j\)。
考虑一种修改方案,显然修改后中间的数会呈现阶梯状。
对于任意一个阶梯\((l,r,x)\),如果它上面的数(\([l,r]\)中\(>x\)的数)的个数大于下面的数的个数(\([l,r]\)中\(<x\)的数),那么我们把它往上移到下一个阶梯的高度一定会更优。
反之我们把它移到下一个阶梯的高度一定会更优。
如果上面和下面的数个数相等,我们随便怎么移动都不会改变这个代价。
因此最终我们一定可以把它移成两个阶梯\((i+1,k,a_i),(k+1,j,a_j)\)。
那么对于LIS中相邻的两数\(a_i,a_j\),最优的修改方案一定是找到某个\(k\),把\(a_{i+1}\sim a_k\)改成\(a_i\),把\(a_{k+1}\sim a_j\)改成\(a_j\)。
我们枚举这个\(k\)。然后计算。
注意到数据随机,所以LIS的期望长度为\(\log n\),因此复杂度正确。
#include<bits/stdc++.h>
#define ll long long
#define pb push_back
using namespace std;
const int N=35007,inf=0x3f3f3f3f;
int read(){int x=0,c=getchar();while(!isdigit(c))c=getchar();while(isdigit(c))x=x*10+c-48,c=getchar();return x;}
ll min(ll a,ll b){return a<b? a:b;}
int abs(int a){return a<0? -a:a;}
int a[N],num[N],f[N];ll g[N],s[N],t[N];vector<int>E[N];
int main()
{
int n=read(),i,k,l,len;
for(i=1;i<=n;++i) a[i]=read()-i;
a[++n]=inf,a[0]=-inf,memset(num,0x3f,sizeof num),num[0]=-inf,num[1]=a[1],f[1]=len=1,memset(g,0x3f,sizeof g),g[0]=0;
for(i=2;i<=n;++i) l=upper_bound(num,num+len+1,a[i])-num,len=max(len,l),f[i]=l,num[l]=min(num[l],a[i]);
for(i=0;i<=n;++i) E[f[i]].pb(i);
for(i=1;i<=n;++i)
for(int j:E[f[i]-1])
{
if(j>i||a[j]>a[i]) continue;
for(k=j;k<=i;++k) s[k]=abs(a[k]-a[j]),t[k]=abs(a[k]-a[i]);
for(k=j+1;k<=i;++k) s[k]+=s[k-1],t[k]+=t[k-1];
for(k=j;k<i;++k) g[i]=min(g[i],g[j]+s[k]-s[j]+t[i]-t[k]);
}
printf("%d\n%lld",n-f[n],g[n]);
}
Luogu P2501 [HAOI2006]数字序列的更多相关文章
- 2021.12.06 P2501 [HAOI2006]数字序列(动态规划+LIS)
2021.12.06 P2501 [HAOI2006]数字序列(动态规划+LIS) https://www.luogu.com.cn/problem/P2501 题意: 现在我们有一个长度为 n 的整 ...
- 洛谷 P2501 [HAOI2006]数字序列 解题报告
P2501 [HAOI2006]数字序列 题目描述 现在我们有一个长度为n的整数序列A.但是它太不好看了,于是我们希望把它变成一个单调严格上升的序列.但是不希望改变过多的数,也不希望改变的幅度太大. ...
- p2501 [HAOI2006]数字序列
传送门 分析 https://www.luogu.org/blog/FlierKing/solution-p2501 对于第二问的感性理解就是有上下两条线,一些点在上面的线的上面或者下面的线的下面,然 ...
- P2501 [HAOI2006]数字序列 (LIS,DP)(未完成)
第二问好迷... #include "Head.cpp" #include <vector> const int N = 35007; vector<int> ...
- 【BZOJ1049】 [HAOI2006]数字序列
BZOJ1049 [HAOI2006]数字序列 dp好题? 第一问 第一问我会做!令\(b_i=a_i-i\),求一个最长不下降子序列. \(n-ans\)就是最终的答案. 第二问 好难啊.不会.挖坑 ...
- 【BZOJ 1049】 1049: [HAOI2006]数字序列 (LIS+动态规划)
1049: [HAOI2006]数字序列 Description 现在我们有一个长度为n的整数序列A.但是它太不好看了,于是我们希望把它变成一个单调严格上升的序列.但是不希望改变过多的数,也不希望改变 ...
- bzoj 1049 [HAOI2006]数字序列
[bzoj1049][HAOI2006]数字序列 Description 现在我们有一个长度为n的整数序列A.但是它太不好看了,于是我们希望把它变成一个单调严格上升的序列.但是不希望改变过多的数,也不 ...
- 【BZOJ1049】【Luogu P2501】 [HAOI2006]数字序列 DP,结论,LIS
很有(\(bu\))质(\(hui\))量(\(xie\))的一个题目. 第一问:求最少改变几个数能把一个随机序列变成单调上升序列. \(Solution:\)似乎是一个结论?如果两个数\(A_i\) ...
- 洛谷P2501 bzoj1049 [HAOI2006]数字序列
题目链接 bzoj 洛谷 题解 第一问: 假如 \(i < j\) 如果 \(j\)能从\(i\)转移过来 显然中间空隙必须足够 例如:\(50\) \(53\) \(53\) \(52\) 就 ...
随机推荐
- jquery keydown()方法 语法
jquery keydown()方法 语法 作用:完整的 key press 过程分为两个部分:1. 按键被按下:2. 按键被松开.当按钮被按下时,发生 keydown 事件.keydown() 方法 ...
- 51 Nod N的阶乘的长度 (斯特林近似)
1058 N的阶乘的长度 基准时间限制:1 秒 空间限制:131072 KB 分值: 0 难度:基础题 收藏 关注 输入N求N的阶乘的10进制表示的长度.例如6! = 720,长度为3. Inp ...
- hdu 5695 百度熊教体育 拓扑排序 好题
Gym Class Time Limit: 6000/1000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others)Total S ...
- 在网页中嵌套网页的方法(frame)
在网页中嵌套网页目前通用的方法是通过 frame 框架来完成,该方法有实际的应用意义.也能很好的解决一些问题. 但是 JS 在操作的时候需要同源(不能跨域), 否则一切 js 相关的操作无法完成. 切 ...
- Python3学习笔记(十):赋值语句和布尔值
一.赋值语句 1.序列解包 多个赋值同时进行: >>> x,y,z = 1, 2, 3 >>> print(x, y, z) 1 2 3 变量交换: >> ...
- LeetCode 141、142环形链表
141题: 首先,先看141题,这个题是比较初级也是比较经典的环形链表题: 给定一个链表,判断链表中是否有环. 进阶:你能否不使用额外空间解决此题? 那么,什么是有环的链表呢: 这个就是有环的链表 题 ...
- [CSP-S模拟测试]:小L的数(数位DP+模拟)
题目传送门(内部题132) 输入格式 第一行一个整数$t$. 接下来$t$行每行一个整数$n$. 输出格式 $t$行,每行一个整数表示答案. 样例 样例输入: 41818231232691052109 ...
- IDM非补丁破解方法
参考 http://tieba.baidu.com/p/3878377959 备份文章 在网络和共享中心中打开防火墙 高级设置->出站规则->新建规则 打开新建规则向导. 程序-> ...
- Java中的Unicode与码点
Java中,可以用\uXXXX表示Unicode字符,例如String s = "\u00X1";XXXX必须为4位,因此码点为U+1D546的字符,需要用两个编码单元表示,例如S ...
- CyclicBarrier源码阅读
一种允许多个线程全部等待彼此都到达某个屏障的同步机制 使用 多个线程并发执行同一个CyclicBarrier实例的await方法时,每个线程执行这个方法后,都会被暂停,只有当最后一个线程执行完awai ...