【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 再竖着算出每一列的长 ...
随机推荐
- php扩展开发2--添加类
1.需要实现的细节 实现一个person类 实现一个doing方法和saying方法 2.第一个扩展 2.1创建类的扩展: [root@bogon ext]# cd /usr/local/src/ph ...
- Apache apxs命令
一.简介 apxs是一个为Apache HTTP服务器编译和安装扩展模块的工具,用于编译一个或多个源程序或目标代码文件为动态共享对象,使之可以用由mod_so提供的LoadModule指令在运行时加载 ...
- python字符串大小写转换
str = "www.w3cSChool.cn"print(str.upper()) # 把所有字符中的小写字母转换成大写字母print(str.lower()) # 把所有字符中 ...
- 【原创测试】MongoDB千万级插入数据测试(MMO在线游戏应用场合)
一.筹备 我们要做一次千万级的MONGODB测试,操作系统选用CentOS 5.5 64位版,基本模拟实际的使用环境,采用单机集群模型(测试单机多CPU情况下的实际效果). 测试基准数据: 服务器配置 ...
- React官方网站学习
React官方网站 英文版 https://reactjs.org/tutorial/tutorial.html React官方网站 中文版 https://react.docschina.org ...
- HDU 3723 Delta Wave (高精度+calelan数)
题意:给定一个图,问你只能向上向下,或者平着走,有多少种方法可以走到最后一个格. 析:首先先考虑,如果没有平的情况就是calelan数了,现在有平的情况,那么就枚举呗,因为数很大,所以要用高精度. 答 ...
- WEB缓存初探
WEB缓存初探 概念理解 缓存--缓存就是数据交换的缓冲区(称作Cache) 缓存 的作用说白了就是用来就近获取东西,比如我们会把已经拿到的常用的东西放在手边(与自己相对较近的地方),方便下次需要时去 ...
- delphi xe6 for android 自带控件LocationSensor优先使用GPS定位的方法
delphi xe6 for android LocationSensor控件默认是优先使用网络定位,对定位精度要求高的应用我们可以修改原码直接指定GPS定位. 修改方法: 将C:\Program F ...
- Jquery queue实例
$(function () { var queueList = [ function () { $("div").animate({ height: 80, top: 40 }, ...
- MSSQL 静态值查询
有些时候可能会需要查询一些静态值 ), (),()) AS tabName ( c1 ) 演变1.多列 ,), (,),(,)) AS tabName ( c1,c2 ) 演变2.聚合 ), (),( ...