罗勇军 → 《算法竞赛·快冲300题》每日一题:“推箱子” ← 差分及前缀和

news2024/11/26 13:49:04

【题目来源】
http://oj.ecustacm.cn/problem.php?id=1819

http://oj.ecustacm.cn/viewnews.php?id=1023

【题目描述】
在一个高度为H的箱子前方,有一个长和高为N的障碍物。
障碍物的每一列存在一个
连续的缺口,第i列的缺口从第l个单位到第h个单位(从底部由0开始数)。
现在请你清理出一条高度为H的通道,使得箱子可以直接推出去。
请输出最少需要清理的障碍物面积。
如下图为样例中的障碍物,长和高度均为5,箱子高度为2。
不需要考虑箱子会掉入某些坑中。最少需要移除两个单位的障碍物可以造出一条高度为2的通道。

   

 【输入格式】
输入第一行为两个正整数N和H,表示障碍物的尺寸和箱子的高度,1≤H≤N≤1000000。
接下来N行,每行包含两个整数li和hi,表示第i列缺口的范围,0≤li≤hi<N。

【输出格式】
输出一个数字表示答案。

【输入样例】
5 2
2 3
1 2
2 3
1 2
2 3

【输出样例】
2

【算法分析】
一、本题箱子高度为H,障碍物的尺寸为N*N,若用 a[i] 表示障碍物第 i 行的空白数量,则问题就抽象为“
从 a[] 中找出连续的 H个 整数,要求它们的和最大”,也即要清理的障碍物面积最小。很显然,此时问题就转化成一个典型的区间求和问题。而区间求和问题,自然而然就要考虑选择差分和前缀和进行优化,避免时间复杂度过大而超时。

二、本题数据规模较大,计算结果会
超过 10 位数。故保险起见,选择 long long 数据类型。

三、本题需用
差分前缀和来优化代码,避免超时。差分与前缀和是一对互逆的操作,常用于求解区间问题。
1.差分主要用于多次对区间进行加减操作的问题。
差分算法涉及的主要操作陈述如下:
(1)构建差分数组
【差分数组概念】设原数组为含有 n 个数的 a 数组(下标常从 1 开始),差分数组为 d 数组(下标常从 1 开始)。其中,令
d[1]=a[1],且对于 i∈[2,n],令 d[i]=a[i]-a[i-1]
【示例】例如,设原数组 a[]=[3 5 9 10 16 18 27] (下标常从 1 开始),则有:
d[1]=a[1]=3,
d[2]=a[2]-a[1]=5-3=2,
d[3]=a[3]-a[2]=9-5=4,
d[4]=a[4]-a[3]=10-9=1,
d[5]=a[5]-a[4]=16-10=6,
d[6]=a[6]-a[5]=18-16=2,
d[7]=a[7]-a[6]=27-18=9,
即差分数组为 d[]=[3 2 4 1 6 2 9]。
(2)对原数组的区间 [le, ri] 进行加减操作
【结论】构造差分数组后,对原数组的区间
[le, ri] 的加减操作就转化为对差分数组的区间端点的操作:d[le]+=x,d[ri+1]-=x显然,这大大降低了算法的时间复杂度
【示例】例如,对原数组 a[]=[3 5 9 10 16 18 27] (下标常从 1 开始)的区间 [2,5] 中的每个数都加 3,则等价于执行d[2]+=3,d[5+1]-=3。
【解析】现在,来分析一下对原数组 a[]=[3 5 9 10 16 18 27] (下标常从 1 开始)执行 d[2]+=3,d[5+1]-=3 后,是否等价于对原数组的区间 [2,5] 中的每个数都加了 3?
由上文分析知,原数组 a[]=[3 5 9 10 16 18 27] 的差分数组为 d[]=[3 2 4 1 6 2 9]。显然,执行 d[2]+=3,d[5+1]-=3 后,原数组的差分数组由 d[]=[3
2 4 1 6 2 9] 变为 d[]=[3 5 4 1 6 -1 9]。
显然,由关系 d[1]=a[1],d[i]=a[i]-a[i-1] (i≥2),知:
a[1]=d[1]=3
a[2]=d[2]+a[1]=5+3=8
a[3]=d[3]+a[2]=4+8=12
a[4]=d[4]+a[3]=1+12=13
a[5]=d[5]+a[4]=6+13=19
a[6]=d[6]+a[5]=-1+19=18
a[7]=d[7]+a[6]=9+18=27
可见,对原数组 a[]=[3
5 9 10 16 18 27] (下标常从 1 开始)执行 d[2]+=3,d[5+1]-=3 后,原数组变为 a[]=[3 8 12 13 19 18 27],原数组区间 [2,5] 内的每个元素确实都加了3。
(3)对原数组的多个区间进行加减操作
【示例】例如,对原数组 a[]=[3 5 9 10 16 18 27] (下标常从 1 开始)的区间 [2,5] 中的每个数都加 3,则等价于执行d[2]+=3,d[5+1]-=3。然后,对区间 [3,6] 中的每个数都减 2(相当于加 -2),则等价于执行 d[3]+=(-2),d[6+1]-=(-2)。最后,对区间 [1,4] 中的每个数都加 5,则等价于执行d[1]+=5,d[4+1]-=5。
【解析】由上文分析知,原数组 a[]=[3 5 9 10 16 18 27] 的差分数组为 d[]=[3 2 4 1 6 2 9]。
执行 d[2]+=3,d[5+1]-=3 后,由 d[]=[3 2 4 1 6 2 9] 变为 d[]=[3
5 4 1 6 -1 9]。
执行 d[3]+=(-2),d[6+1]-=(-2) 后,由 d[]=[3
5 4 1 6 -1 9] 变为 d[]=[3 5 2 1 6 -1 11]。​​​​​​​
执行 d[1]+=5,d[4+1]-=5 后,由 d[]=[3
5 2 1 6 -1 11] 变为 d[]=[8 5 2 1 1 -1 11]。​​​​​​​
然后,仅观察最后生成的差分数组 d[]=[
8 5 2 1 1 -1 11],且依据关系 d[1]=a[1],d[i]=a[i]-a[i-1] (i≥2),知:
a[1]=d[1]=8
a[2]=d[2]+a[1]=5+8=13
a[3]=d[3]+a[2]=2+13=15
a[4]=d[4]+a[3]=1+15=16
a[5]=d[5]+a[4]=1+16=17
a[6]=d[6]+a[5]=-1+17=16
a[7]=d[7]+a[6]=11+16=27
即,经过多轮对原数组的差分数组端点进行操作后,原数组 a[]=[8 13 15 16 17 16 27]。
为了验证比较,现在按上文对原数组 a[]=[3 5 9 10 16 18 27] 给定的区间进行操作的内容如下:
对区间 [2,5] 中的每个数都加 3,由 a[]=[8 13 15 16 17 16 27] 变为 a[]=[3
8 12 13 19 18 27]。
对区间 [3,6] 中的每个数都减 2,由 a[]=[3
8 12 13 19 18 27] 变为 a[]=[3 8 10 11 17 16 27]。
对区间 [1,4] 中的每个数都加 5,由 a[]=[3 8
10 11 17 16 27] 变为 a[]=[8 13 15 16 17 16 27]。
显然,与利用差分数组算出来的结果一样。
可见,若给定的原数组序列特别长,则差分数组对端点的操作将比原数组对区间的操作在得到计算结果上
快得多,虽然它俩在计算结果上是一样的。
2.
前缀和主要用于多次对区间进行求和的问题。
前缀和,无论是一维前缀和还是二维前缀和,通常都用于快速对区间进行求和。 它们的思想都是利用给定的数据预先处理出一个前缀和数组
sum[],之后在计算区间和的时候查表,从而可以大大降低算法的时间复杂度。参见:https://blog.csdn.net/hnjzsyjyj/article/details/120265452
一维前缀和数组预处理过程:sum[i]=sum[i-1]+a[i]
一维区间和计算过程:sum[y]-sum[x-1]     (y≥x)
二维前缀和数组预处理过程:sum[i][j]=sum[i-1][j]+sum[i][j-1]-sum[i-1][j-1]+a[i][j]
二维区间和计算过程:sum[x2][y2]-sum[x1-1][y2]-sum[x2][y1-1]+sum[x1-1][y1-1]     (y2≥y1,x2≥x1)

四、题目中陈述每一列存在一个连续的缺口,所以用暴力法统计此连续的缺口中的空白数量,计算量将会达到 O(NH)。由于 N 和 H 的数据量最高都可达到10^6,所以 NH 的规模将可能会超过 10^12,显然暴力法会超时。因此,需要利用差分算法将对连续区间的求和操作转化为对区间端点的操作,必然大大降低算法的时间复杂度。
本题中,对连续区间的差分操作(即构建差分方程)见如下代码:

int li,hi;
for(int i=1; i<=n; i++) { //Create differential array
    scanf("%d %d",&li,&hi);
    d[li]+=1; //d[li]++;
    d[hi+1]-=1; //d[hi+1]--;
}

可见,对区间的差分操作必须是对连续区间进行操作的。

五、在连续区间上应用差分算法的常见步骤:差分数组 → 原数组 → 前缀和
(1)对连续区间 [le,ri] 利用“d[le]+=1; d[ri+1]-=1;”构造差分数组d[];
(2)利用“
d[1]=a[1],且对于 i∈[2,n],d[i]=a[i]-a[i-1]”构造原数组a[];
(3)利用“
sum[i]=sum[i-1]+a[i]”构造前缀和数组sum[]。

【算法代码】

#include <bits/stdc++.h>
using namespace std;

typedef long long ll;
const int maxn=1e6+5;
ll d[maxn]; //differential array
ll a[maxn]; //number of obstacle's blank
ll sum[maxn]; //prefix sum

int main() {
    int n,h;
    scanf("%d %d",&n,&h);

    int li,hi;
    for(int i=1; i<=n; i++) { //Create differential array
        scanf("%d %d",&li,&hi);
        d[li]+=1; //d[li]++;
        d[hi+1]-=1; //d[hi+1]--;
    }

    for(int i=1; i<=n; i++) a[i]=a[i-1]+d[i-1];
    for(int i=1; i<=n; i++) sum[i]=sum[i-1]+a[i];

    ll ans=sum[h-1];
    for(int i=1; i+h-1<=n; i++) {
        ans=max(ans,sum[i+h-1]-sum[i-1]);
    }

    cout<<(ll)n*h-ans<<endl;
    return 0;
}


/*
in:
5 2
2 3
1 2
2 3
1 2
2 3

out:
2
*/




【参考文献】
https://blog.csdn.net/weixin_43914593/article/details/131730112
http://oj.ecustacm.cn/viewnews.php?id=1023
https://blog.csdn.net/weixin_43914593/category_12377073.html
https://blog.csdn.net/m0_51769031/article/details/123973620
https://www.cnblogs.com/jue1e0/p/15065006.html
https://blog.csdn.net/weixin_54442315/article/details/122663584




​​​​​​​

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/867616.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【c语言】通讯录(静态)

小张刚学习完结构体&#xff0c;枚举&#xff0c;联合相关的知识&#xff0c;实践实践&#xff0c;写一个通讯录呗&#xff01; 通讯录的功能 1.通讯录可存放100的信息 2.信息的内容姓名&#xff0c;性别&#xff0c;年龄&#xff0c;电话&#xff0c;地址 3.支持增加联系人 4.…

许可是开源的基石,协作才是未来! KCC@南京第二次活动

自从疫情结束后&#xff0c;作为“穷游”之城的南京&#xff0c;且具有高性价比的六朝古都&#xff0c;来旅行的人们也是络绎不绝&#xff0c;恰逢暑假之时更为火爆。即便在炎炎夏日&#xff0c;也依然抵挡不住开源人的那颗赤诚之心。 此次活动不仅是本地的开源人&#xff0c;花…

树莓派RP2040 用Arduino IDE安装和编译

目录 1 Arduino IDE 1.1 IDE下载 1.2 安装 arduino mbed os rp2040 boards 2 编程-烧录固件 2.1 打开点灯示例程序 2.2 选择Raspberry Pi Pico开发板 2.3 编译程序 2.4 烧录程序 2.4.1 Raspberry Pi Pico开发板首次烧录提示失败 2.4.2 解决首次下载失败问题 2.4.2.1…

uniapp的UI框架组件库——uView

在写uniapp项目时候&#xff0c;官方所推荐的样式库并不能满足日常的需求&#xff0c;也不可能自己去写相应的样式&#xff0c;费时又费力&#xff0c;所以我们一般会去使用第三方的组件库UI&#xff0c;就像vue里我们所熟悉的elementUI组件库一样的道理&#xff0c;在uniapp中…

基于grpc从零开始搭建一个准生产分布式应用(1) - 开始准备

开始前必读&#xff1a;​​基于grpc从零开始搭建一个准生产分布式应用(0) - quickStart​​ 本来笔者并不想开设这个系列&#xff0c;因为工作量比较大&#xff0c;另外此专题的技术点也偏简单。最近复盘了下最近的工作&#xff0c;发现一个问题就是各个互联网大厂一般都会有…

hbase 报错 Master passed us a different hostname to use; was=

原因 wsl2的 /etc/hosts 配置的不兼容,我这里是ubuntu22 修改为 127.0.0.1 ubuntu22 即可

Blazor 调试控制台

文章目录 设置 设置 Blazor项目启动之后&#xff0c;有好几种项目设置&#xff0c;我其实想要这一种控制台 直接Console.log就行了 public void LoginBtn(){Console.WriteLine("登录");//navigationManager.NavigateTo("/index");}

STM32 LL库开发

一、STM32开发方式 标准库开发&#xff1a;Standard Peripheral Libraries&#xff0c;STDHAL库开发&#xff1a;Hardware Abstraction Layer&#xff0c;硬件抽象层LL库开发&#xff1a;Low-layer&#xff0c;底层库 二、HAL库与LL库开发对比 ST在推行HAL库的时候&#xff0c;…

手机怎样换ip地址 更改手机IP地址有哪些方式

ip地址怎么改&#xff1a;使用深度ip转换器 在互联网时代&#xff0c;IP地址扮演着网络世界中的独特标识符。它是我们在上网时必不可少的元素&#xff0c;负责为设备提供独立的身份&#xff0c;并将信息传输到正确的目的地。然而&#xff0c;有时我们需要改变IP地址&#xff0c…

婚恋交友h5多端小程序开源版开发

婚恋交友h5多端小程序开源版开发 以下是婚恋交友H5多端小程序的功能列表&#xff1a; 用户注册和登录&#xff1a;用户可以通过手机号码或第三方账号注册和登录。个人信息填写&#xff1a;用户可以填写个人基本信息&#xff0c;包括姓名、性别、年龄、身高、体重、学历、职业等…

第11集丨Vue 江湖 —— 过滤器(filter)

目录 一、过滤器1.1 局部过滤器1.2 全局过滤器1.3 过滤器的串联1.4 案例 二、BootCDN2.1 在BootCDN下载dayjs2.2 dayjs官方文档 一、过滤器 过滤器&#xff1a; 定义&#xff1a;对要显示的数据进行特定格式化后再显示(适用于一些简单逻辑的处理&#xff09;。语法: a. 注册过…

阿里巴巴面试题---考察对底层源代码的熟悉程度

题目如图所示: 很多人可能会觉得两个输出都会是false,因为我们都会觉得""比较的是引用类型的地址,虽然放入的值都一样但是重新创造了新对象,地址不一样,所以结果都是false. 然而,当我们运行程序会发现结果都是false. 下面,我们来分析为什么是这样的结果. 我们知道…

nodejs+vue+elementui健身俱乐部网站rix1z

为设计一个安全便捷&#xff0c;并且使用户更好获取本健身俱乐部管理信息&#xff0c;本文主要有安全、简洁为理念&#xff0c;实现用户快捷寻找健身课程、健身器材、会员卡信息、新闻公告等信息&#xff0c;从而解决健身俱乐部管理信息复杂难辨的问题。该系统以vue架构技术为基…

Linux 目录和文件常见操作

就常见的命令&#xff1a; pwd pwd 显示当前的目录 目录迁移 我以如下的目录大致结构做一个简单的例子 cd 迁移到指定的路径&#xff0c;可以指定相对路径和绝对路径&#xff0c;默认相对 .指向当前路径&#xff0c;…/ 指向上一级的目录。 ls 列出文件及其目录 命令选…

取个对象值导致系统崩溃

取个对象值导致系统崩溃 前言 想必各位小伙经常在项目中遇到一些错误&#xff0c;取对象值的时候&#xff0c;经常报错,又或者某些项目突然就挂经常都是出现在一些对象取值上面&#xff0c;然后就被领导一顿训斥 报错分析 例如&#xff1a; 下面这个报错大家想必不会陌生&am…

华尔街之狼

&#xff08;1&#xff09; 我最近在重看一本书《物理学家走进华尔街》&#xff0c;顺便我还又重看了一遍《华尔街之狼》。 华尔街之狼&#xff0c;我最感兴趣三点&#xff1a; 垃圾产品&#xff1a;退市的垃圾股粉单 垃圾顾客&#xff1a;没有钱&#xff0c;但想发财的平民。就…

掌握Python的X篇_28_python包管理工具pip命令

本篇将会介绍在实际使用python中最能节省效率的内容&#xff0c;利用第三方库拿来就用。 文章目录 1. pip命令是什么2. pip相关操作2.1 list2.2 install2.3 uninstall2.4 导出和导入2.4.1 freeze命令2.4.2 “-r” 3. 国内镜像4. Python Packges Index网站 1. pip命令是什么 p…

mysql安装配置教程

mysql下载 mysql官网 mysql英文官网下载 mysql安装 解压安装包,如下效果 2.配置初始化文件my.ini 在根目录下创建一个txt文件&#xff0c;名字叫my&#xff0c;文件后缀为ini 之后复制下面这个代码放在文件下 &#xff08;新解压的文件没有my.ini文件&#xff0c;需自行创建…

QT界面的布局

QT界面的布局 qt 下的布局: 1.水平布局2.垂直布局3格布局 图片记得设置大小后在进行布局 文字居中

c++11-14-17_内存管理(RAII)_多线程

文章目录 前言&#xff1a;什么是RAII&#xff1f;指针/智能指针&#xff1a;使用智能指针管理内存资源&#xff1a;unique_ptr的使用&#xff1a;自定义删除器&#xff1a; shared_ptr的使用&#xff1a;shared_ptr指向同一个对象的不同成员&#xff1a;自定义删除函数&#x…