【DP】【单调队列】洛谷 P2216 [HAOI2007]理想的正方形 题解
算是单调队列的复习吧,不是很难
题目描述
有一个$a\times b$的整数组成的矩阵,现请你从中找出一个$n\times n$的正方形区域,使得该区域所有数中的最大值和最小值的差最小。
输入输出格式
输入格式:
第一行为$3$个整数,分别表示$a,b,n$的值。
第二行至第$a+1$行每行为$b$个非负整数,表示矩阵中相应位置上的数。每行相邻两数之间用一空格分隔。
输出格式:
仅一个整数,为$a\times b$矩阵中所有“$n\times n$正方形区域中的最大整数和最小整数的差值”的最小值。
输入输出样例
输入样例#1:5 4 2
1 2 5 6
0 17 16 0
16 17 2 1
2 10 2 1
1 2 2 2输出样例#1:1说明
问题规模
(1)矩阵中的所有数都不超过$1,000,000,000$
(2)$20\%$的数据$2\le a,b\le 100,n\le a,n\le b,n\le 10$
(3)$100\%$的数据$2\le a,b\le 1000,n\le a,n\le b,n\le 100$
题解:
乍一看好像是类似前缀和二维容斥,可以$O(n^3)$搞。就是维护每个点向左上角一个边长为$k$的正方形中,最大值和最小值。发现只需要通过$k-1$递推,不用容斥
不过这样的时空都是$O(n^3)$的,数据范围是$1,000$,因此考虑优化。
事实上对于每个点只框定了这$n\times n$的范围的话,也就是宽度$latex n$是一定的,可以想到单队入门题滑动的窗口。不过这里前面每格都还维护了上面$n$个,那么我们就可以先预处理出每个点从自己开始上面$n$个中最大和最小值,这个可以用普通单队处理出来。要注意的是得维护两个单队,一个最小一个最大。
最后只统计右下角$(a-n+1)(b-n+1)$区域的答案,因为只有以这些点为右下角才能凑出完整的$n\times n$正方形来。(剩下部分虽然做了贡献但是不能被统计到答案……伤心:()
Code:
#include<cstdio>
#include<cstring>
int q1[1010],l1=0,r1=0;//最大
int q2[1010],l2=0,r2=0;//最小
int a[1010][1010];//向上n个最大
int b[1010][1010];//向上n个最小
int c[1010][1010];//原来的矩阵
int main()
{
memset(b,0x3f,sizeof(b));//注意这里b要取最小值所以要赋初值
int n,m,k;
scanf("%d%d%d",&n,&m,&k);
for(int i=1;i<=n;++i)
for(int j=1;j<=m;++j)
scanf("%d",&c[i][j]);
for(int i=1;i<=m;++i)
{
l1=0,r1=0;
l2=0,r2=0;
for(int j=1;j<=n;++j)
{
if(l1<r1&&q1[l1+1]<=j-k)//超出范围
++l1;
while(l1<r1&&c[q1[r1]][i]<c[j][i])//保证单调(减
--r1;
q1[++r1]=j;
a[j][i]=a[j][i]>c[q1[l1+1]][i]?a[j][i]:c[q1[l1+1]][i]; if(l2<r2&&q2[l2+1]<=j-k)
++l2;
while(l2<r2&&c[q2[r2]][i]>c[j][i])//保证单调(增
--r2;
q2[++r2]=j;
b[j][i]=b[j][i]<c[q2[l2+1]][i]?b[j][i]:c[q2[l2+1]][i];
}
}
int ans=0x3fffffff;
for(int i=k;i<=n;++i)
{
l1=0,r1=0;
l2=0,r2=0;
for(int j=1;j<=m;++j)
{
if(l1<r1&&q1[l1+1]<=j-k)
++l1;
while(l1<r1&&a[i][j]>a[i][q1[r1]])
--r1;
q1[++r1]=j;
if(l2<r2&&q2[l2+1]<=j-k)
++l2;
while(l2<r2&&b[i][j]<b[i][q2[r2]])
--r2;
q2[++r2]=j;
if(j>=k)
ans=ans<a[i][q1[l1+1]]-b[i][q2[l2+1]]?ans:a[i][q1[l1+1]]-b[i][q2[l2+1]];
}
}
printf("%d\n",ans);
return 0;
}
【DP】【单调队列】洛谷 P2216 [HAOI2007]理想的正方形 题解的更多相关文章
- 洛谷 P2216 [HAOI2007]理想的正方形
P2216 [HAOI2007]理想的正方形 题目描述 有一个a*b的整数组成的矩阵,现请你从中找出一个n*n的正方形区域,使得该区域所有数中的最大值和最小值的差最小. 输入输出格式 输入格式: 第一 ...
- 洛谷P2216: [HAOI2007]理想的正方形 单调队列优化DP
洛谷P2216 )逼着自己写DP 题意: 给定一个带有数字的矩阵,找出一个大小为n*n的矩阵,这个矩阵中最大值减最小值最小. 思路: 先处理出每一行每个格子到前面n个格子中的最大值和最小值.然后对每一 ...
- 洛谷 P2216 [HAOI2007]理想的正方形 || 二维RMQ的单调队列
题目 这个题的算法核心就是求出以i,j为左上角,边长为n的矩阵中最小值和最大值.最小和最大值的求法类似. 单调队列做法: 以最小值为例: q1[i][j]表示第i行上,从j列开始的n列的最小值.$q1 ...
- 洛谷P2216 HAOI2007 理想的正方形 (单调队列)
题目就是要求在n*m的矩形中找出一个k*k的正方形(理想正方形),使得这个正方形内最值之差最小(就是要维护最大值和最小值),显然我们可以用单调队列维护. 但是二维平面上单调队列怎么用? 我们先对行处理 ...
- [洛谷P2216][HAOI2007]理想的正方形
题目大意:有一个$a\times b$的矩阵,求一个$n\times n$的矩阵,使该区域中的极差最小. 题解:二维$ST$表,每一个点试一下是不是左上角就行了 卡点:1.用了一份考试时候写的二维$S ...
- 洛谷 P2216 [HAOI2007]理想正方形
洛谷 巨说这是一道单调队列好题,但是我并不是用单调队列做的诶. 如果往最暴力的方向去想,肯定是\(n^3\)的\(dp\)了. \(f[i][j][k]\)代表当前正方形的左上角定点是\((i,j)\ ...
- BZOJ1047或洛谷2216 [HAOI2007]理想的正方形
BZOJ原题链接 洛谷原题链接 显然可以用数据结构或\(ST\)表或单调队列来维护最值. 这里采用单调队列来维护. 先用单调队列维护每一行的最大值和最小值,区间长为正方形长度. 再用单调队列维护之前维 ...
- 洛谷 2216 [HAOI2007]理想的正方形
题目戳这里 一句话题意 给你一个a×b的矩形,求一个n×n的子矩阵,矩阵里面的最大值和最小值之差最小. Solution 这个题目许多大佬都是单调队列,但是我不是很会,只好用了比较傻逼的方法: 首先我 ...
- 【单调队列】bzoj 1407 [HAOI2007]理想的正方形
[题意] 给定一个n*m的矩阵,求所有大小为k*k的正方形中(最大值-最小值)的最小值 [思路] 先横着算出每一行的长度为k的窗口内的最大值,变成一个n*(m-k+1)的矩阵mx 再竖着算出每一列的长 ...
随机推荐
- DEDE 5.7中各函数所在的文件和位置
/include/taglib/tag.lib.php 2 //function GetTags()/include/payment/yeepay.php 415 function log_resul ...
- SQL Server误区30日谈 第26天 SQL Server中存在真正的“事务嵌套”
误区 #26: SQL Server中存在真正的“事务嵌套”错误 嵌套事务可不会像其语法表现的那样看起来允许事务嵌套.我真不知道为什么有人会这样写代码,我唯一能够想到的就是某个哥们对SQL Serve ...
- Docker学习笔记_Dockerfile基本知识
Dockerfile由一行行命令语句组成,并支持以#开头的注释行. 1.编写一个Dockerfile文件 创建一个空的Docker工作目录,进入该目录,使用sudo vim Dockerfile指令新 ...
- Docker学习笔记_下载镜像更换为国内源,实现快速下载image
1.编辑/etc/docker/daemon.json,增加下面内容: { "registry-mirrors": ["https://registry.docker-c ...
- linux删除文件后磁盘空间未释放的问题
很可能是该文件还被其它进程使用. 使用: lsof | grep deleted | grep $FILE_NAME 可以看到正使用该文件的进程,将之kill即可.也可以查看进程来验证: ls -l ...
- 38.NOW() 函数
NOW 函数返回当前的日期和时间. 提示:如果您在使用 Sql Server 数据库,请使用 getdate() 函数来获得当前的日期时间. SQL NOW() 语法 SELECT NOW() FRO ...
- 互联网+大数据解决方案(ppt)
from: 互联网+大数据解决方案(ppt) 导读:大数据(bigdata),或称巨量资料,指的是所涉及的资料量规模巨大到无法透过目前主流软件工具,在合理时间内达到撷取.管理.处理.并整理成为帮助企业 ...
- TP5图片上传
/*图片上传*/ public function upload(){ // 获取表单上传文件 例如上传了001.jpg $file = request()->file('file'); // 移 ...
- 如何确定tabcontrol哪一页码是活跃页???
tabControl1.SelectedIndex属性 显示了现在显示的是哪一页码内的控件.
- ASP.NET框架获取数据字典数据做成树的格式
private List<TreeEntity> treeList = new List<TreeEntity>();//创建一个树的List集合 public ActionR ...