删区间

题意:

给出一个长度为的数组,你每次需要选出一个长度大于1的区间[, ]并删掉它,代价

是左右端点的元素之差的绝对值| − |,之后再将左右两个数组接起来构成一个新的数组。

你的任务是要求出删除整个数组的最小代价和。

题解:

40pts

暴力区间 dp

70pts:

设 \(f[i]\) 表示删完 \(1-i\) 这段区间的最小代价

转移时枚举这次删去的区间的左端点,在取个 \(min\) 就可以.

具体方程长这样

f[i] = min(f[i], f[j-1] + abs(a[i]-a[j])

100pts

观察一下上面的转移柿子,发现是不可以用单调队列优化的,一个取绝对值就很难处理。

当时考试的时候我就卡在这里没想出来,然后就暴力滚粗了。

实际上,我们的转移柿子可以写成这样:

[] = [ − 1] − + , ≤
f[i] = [ − 1] + − , >

可以维护两棵权值线段树,一个维护最小值 \(f[j-1] - a[j]\) 一个维护 \(f[j-1] + a[j]\)

在 \(1-Ai\) 区间里取最小值 \(f[j-1] - a[j]\) 在 \(Ai - \infty\) 区间里取最小值 \(f[j-1] + a[j]\)

最后不要忘记把权值离散化;

Code

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
using namespace std;
#define int long long
const int N = 5e5+10;
const int inf = 1e13;
int n,tot,f[N],a[N],h[N],rk[N],tr[N<<2][2];
inline int read()
{
int s = 0, w = 1; char ch = getchar();
while(ch < '0' || ch > '9'){if(ch == '-') w = -1; ch = getchar();}
while(ch >= '0' && ch <= '9'){s =s * 10+ch - '0'; ch = getchar();}
return s * w;
}
void up(int now,int o)
{
tr[o][now] = min(tr[o<<1][now],tr[o<<1|1][now]);
}
void build(int now,int o,int L,int R)
{
tr[o][now] = inf;
if(L == R)
{
tr[o][now] = inf;
return;
}
int mid = (L + R)>>1;
build(now,o<<1,L,mid);
build(now,o<<1|1,mid+1,R);
}
void chenge(int now,int o,int L,int R,int x,int val)
{
if(L == R)
{
tr[o][now] = min(tr[o][now],val);
return;
}
int mid = (L + R)>>1;
if(x <= mid) chenge(now,o<<1,L,mid,x,val);
if(x > mid) chenge(now,o<<1|1,mid+1,R,x,val);
tr[o][now] = min(tr[o<<1][now],tr[o<<1|1][now]);
}
int query(int now,int o,int L,int R,int l,int r)
{
int res = inf;
if(l <= L && r >= R) return tr[o][now];
int mid = (L + R)>>1;
if(l <= mid) res = min(res,query(now,o<<1,L,mid,l,r));
if(r > mid) res = min(res,query(now,o<<1|1,mid+1,R,l,r)); return res;
}
signed main()
{
// freopen("remove.in","r",stdin);
// freopen("remove.out","w",stdout);
n = read();
for(int i = 1; i <= n; i++)
{
a[i] = h[i] = read();
}
sort(a+1,a+n+1);
tot = unique(a+1,a+n+1)-a-1;
for(int i = 1; i <= n; i++)
{
rk[i] = lower_bound(a+1,a+tot+1,h[i])-a;
}
build(0,1,1,tot); build(1,1,1,tot);
f[1] = inf;
for(int i = 2; i <= n; i++)
{
chenge(0,1,1,tot,rk[i-1],f[i-2] - h[i-1]);
chenge(1,1,1,tot,rk[i-1],f[i-2] + h[i-1]);
int t1 = query(0,1,1,tot,1,rk[i]) + h[i];
int t2 = query(1,1,1,tot,rk[i],tot) - h[i];
f[i] = min(t1,t2);
}
printf("%lld\n",f[n]);
fclose(stdin); fclose(stdout);
return 0;
}

9.13 考试 T2 区间的更多相关文章

  1. 2021.9.13考试总结[NOIP模拟52]

    T1 路径 考虑每一位的贡献,第$i$位每$2^i$个数会变一次,那么答案为$\sum_{i=1}^{log_2n} \frac{n}{2^i}$. $code:$ 1 #include<bit ...

  2. 2021.8.13考试总结[NOIP模拟38]

    T1 a 入阵曲.枚举矩形上下界,之后从左到右扫一遍.用树状数组维护前缀和加特判可以$A$,更保险要脸的做法是双指针扫,因为前缀和单调不减. $code:$ 1 #include<bits/st ...

  3. 2019.3.12考试&2019.3.13考试&ESTR

    过程:太菜了,不写了 T1 基环树直径,一定学 T2 树上斜率优化,类似购票,数据结构/分治算法,一定改 (把点按深度排序倒着跑2e7次斜率优化也能A,orz zyz) T3 CC原题,码码码,一定补 ...

  4. 某考试T2 frog

    题目背景 无 题目描述 数轴上有 n 只青蛙,分别编号为 1 到 n.青蛙 i 的初始位置的坐标为 xi. 它们准备进行如下形式的移动:每轮包括 m 次跳跃,第 i 次跳跃由青蛙 ai(1 < ...

  5. 某考试 T2 Tree

    2 树 2.1 题目描述 给一棵n 个节点的树,节点分别编号为0 到n - 1.你可以通过如下的操作来修改这棵树:首先先删去树上的一条边,此时树会分裂为两个连通块,然后在两个连通块之间加上一条新的边使 ...

  6. 某考试 T2 yja

    2.1 Description 在平面上找 n 个点, 要求这 n 个点离原点的距离分别为 r1, r2, ..., rn. 最大化这 n 个点构成的凸包面积, 凸包上的点的顺序任意. 2.2 Inp ...

  7. 题解 2020.10.24 考试 T2 选数

    题目传送门 题目大意 见题面. 思路 本来以为zcx.pxj变强了,后来发现是SPJ出问题了...考试的时候感觉有点人均啊...结果自己还是只想出来一半. 我们假设 \(f(x)=(\lfloor\f ...

  8. NOI-OJ 1.13 ID:23 区间内的真素数

    整体思路 这里需要大量使用素数,必须能够想到只求出M到N之间的素数是不够的,因为M到N之间数字的反序有可能是大于M或小于N的数字,例如M=2,N=20,那么19的反序91大于20,所以使用埃拉拖色尼算 ...

  9. 【nowcoder】 4th T2 区间

    题目链接:https://www.nowcoder.com/acm/contest/175/B 当你为时间复杂度挠头的时候 别人已经33行拿满分了 #include<cstdio> #in ...

随机推荐

  1. Java-学习日记(100 == 100为true,1000 == 1000却为false?)

    Integer底层设计 100 == 100为true,1000 == 1000却为false? 之前也写过String的==与equals的注意点,这次写下Integer的底层设计,不妨先运行下下面 ...

  2. Codeforces1312E Array Shrinking 区间DP

    题意 给你一个数组\(a\),只要满足\(a_i=a_{i+1}\)就可以将这两个元素合并成一个值为\(a_i+1\)的元素,问数组最小长度. 解题思路 记得之前某场的F和这题差不多,当时好像是相邻且 ...

  3. .Net在Windows上使用Jenkins做CI/CD的那些事

    背景 最近入职了一家新公司,公司各个方面都让我非常的满意,我也怀着紧张与兴奋的心情入职后,在第一天接到了领导给我的第一个任务——把整个项目的依赖引用重新整理并实施项目的CI/CD. 本篇的重点主要分享 ...

  4. SpringBoot2 引入 Aop

    一步小心就掉进坑里面了:SpringBoot2 引入 Aop 不生效 SpringBoot2.1.3版本 首先,引入依赖 <!--面向切面--> <dependency> &l ...

  5. java 将map转为实体类

    使用反射将map转为对象,如果不使用反射的话需要一个get一个set写起来麻烦,并且不通用,所以写了一个通用的方法将map集合转为对象,直接看代码,注释也都挺清楚的 public static < ...

  6. Bypass windous/mac 登陆密码

    前言 如题,在52破解里看到一个非常好用的工具 Kon-Boot 2.7 功能 不会去擦除windows密码 不会修改windows文件 此外,Kon-Boot的最新版是目前世界上唯一的一个能够绕过W ...

  7. 《Offer一箩筐》一份高质量「简历」撰写指南,望打扰!!

    「MoreThanJava」 宣扬的是 「学习,不止 CODE」. 如果觉得 「不错」 的朋友,欢迎 「关注 + 留言 + 分享」,文末有完整的获取链接,您的支持是我前进的最大的动力! Hi~ 这里是 ...

  8. Conscription(POJ 3723)

    原题如下: Conscription Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 16584   Accepted: 57 ...

  9. redis加固:修改默认端口6379、密码不为空、内网服务器访问

    一.windows下redis加固: 1.修改redis密码+修改redis端口 1.1.找到服务当中redis的属性配置文件是哪个   这个是我的"D:\Program Files\Red ...

  10. python中eval()

    eval()执行简单的python代码(个人感觉像是执行表达式)