理想的正方形 bzoj-1047 HAOI-2007

题目大意:有一个a*b的整数组成的矩阵,现请你从中找出一个n*n的正方形区域,使得该区域所有数中的最大值和最小值的差最小。

注释:$2\le a,b,n\le 10^3$,$n\le min(a,b)$。

想法:我的思路简直要死。通常的,我们优化暴力来完成对题目的求解。首先,想暴力。漂亮的暴力没想到,倒是想到一个a*b*n*n的,就是枚举每一个点,如果这个点可以作为n*n正方形的左上角,我就暴力枚举这个正方形的所有点。时间复杂度:O((a-n)*(b-n)*n*n)O(挖坑代填过不去)。想怎么优化:首先我们想,暴力的时候是连续的将n*n个数取最大值,我们可以怎么优化?我们可以对于每一行来讲维护一个窗口长度为n的单调队列来求出以每一个点结尾的前n个数的最值。然后我.. ....tm自以为是正解然后开始敲。自然T了之后还不知道怎么肥四,以为bz评测机又jb炸了。仔细分析了一下发现不太对。总的时间复杂度是a*b*n的,满的话是$10^9$的,不T才怪... ...想想再优化优化就好了嘛。对于求出来的矩阵,maxn[i][j]表示原矩阵以(i,j)为起点前n个数的最值。我们可以对maxn矩阵再维护一个窗口长度为n的单调队列,这样的话查询就是O(1)的了qwq.

最后,附上丑陋的代码... ...

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#define inf 2000000000
#define ll long long
using namespace std;
inline int read()
{
int x=0,f=1;char ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
return x*f;
}
int a,b,n;
int v[1005][1005],mx[1005][1005],mn[1005][1005],t1[1005],t2[1005];
int val[1005],pos[1005];
void pre()
{
int l,r;
for(int i=1;i<=a;i++)
{
l=1,r=1;
for(int j=1;j<=b;j++)
{
while(l<r&&val[r-1]<=v[i][j])r--;
val[r]=v[i][j];pos[r]=j;r++;
if(pos[l]==j-n)l++;
if(j>=n)mx[i][j]=val[l];
}
l=1,r=1;
for(int j=1;j<=b;j++)
{
while(l<r&&val[r-1]>=v[i][j])r--;
val[r]=v[i][j];pos[r]=j;r++;
if(pos[l]==j-n)l++;
if(j>=n)mn[i][j]=val[l];
}
}
}
void solve()
{
int ans=inf;
int l,r;
for(int i=n;i<=b;i++)
{
l=1,r=1;
for(int j=1;j<=a;j++)
{
while(l<r&&val[r-1]>=mn[j][i])r--;
val[r]=mn[j][i];pos[r]=j;r++;
if(pos[l]==j-n)l++;
if(j>=n)t1[j]=val[l];
}
l=1,r=1;
for(int j=1;j<=a;j++)
{
while(l<r&&val[r-1]<=mx[j][i])r--;
val[r]=mx[j][i];pos[r]=j;r++;
if(pos[l]==j-n)l++;
if(j>=n)t2[j]=val[l];
}
for(int i=n;i<=a;i++)ans=min(ans,t2[i]-t1[i]);
}
printf("%d\n",ans);
}
int main()
{
a=read();b=read();n=read();
for(int i=1;i<=a;i++)
for(int j=1;j<=b;j++)
v[i][j]=read();
pre();
solve();
return 0;
}

小结:单调队列是优化dp的一种比较优秀的手段。而且好写好调,比什么单调栈强多了... ...

[bzoj1047][HAOI2007]理想的正方形_动态规划_单调队列的更多相关文章

  1. [luoguP2216] [HAOI2007]理想的正方形(二维单调队列)

    传送门 1.先弄个单调队列求出每一行的区间为n的最大值最小值. 2.然后再搞个单调队列求1所求出的结果的区间为n的最大值最小值 3.最后扫一遍就行 懒得画图,自己体会吧. ——代码 #include ...

  2. [luogu2216 HAOI2007] 理想的正方形 (2dST表 or 单调队列)

    题目描述 有一个ab的整数组成的矩阵,现请你从中找出一个nn的正方形区域,使得该区域所有数中的最大值和最小值的差最小. 输入输出格式 输入格式: 第一行为3个整数,分别表示a,b,n的值 第二行至第a ...

  3. BZOJ1047: [HAOI2007]理想的正方形 [单调队列]

    1047: [HAOI2007]理想的正方形 Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 2857  Solved: 1560[Submit][St ...

  4. bzoj千题计划215:bzoj1047: [HAOI2007]理想的正方形

    http://www.lydsy.com/JudgeOnline/problem.php?id=1047 先用单调队列求出每横着n个最大值 再在里面用单调队列求出每竖着n个的最大值 这样一个位置就代表 ...

  5. BZOJ1047[HAOI2007]理想的正方形——二维ST表

    题目描述 有一个a*b的整数组成的矩阵,现请你从中找出一个n*n的正方形区域,使得该区域所有数中的最大值和最小值的差最小. 输入 第一行为3个整数,分别表示a,b,n的值第二行至第a+1行每行为b个非 ...

  6. BZOJ1047: [HAOI2007]理想的正方形

    传送门 蛤省省选果然水啊,我这种蒟蒻都能一遍A. 横向纵向维护两个单调队列,做两次求最大和最小的,总复杂度$O(NM)$ 码农题,考察代码实现能力 //BZOJ 1047 //by Cydiater ...

  7. [BZOJ1047][HAOI2007]理想的正方形(RMQ+DP)

    题意 有一个a*b的整数组成的矩阵,现请你从中找出一个n*n的正方形区域,使得该区域所有数中的最大值和最小值的差最小. 思路 RMQ求 再DP 代码 #include<cstdio> #i ...

  8. 【单调队列】bzoj1047 [HAOI2007]理想的正方形

    先把整个矩阵处理成b[n][m-K+1].c[n][m-K+1]大小的两个矩阵,分别存储每行每K个数中的最大.最小值,然后再通过b.c处理出d.e分别表示K*K大小的子矩阵中的最大.最小值即可.单调队 ...

  9. [BZOJ1047][HAOI2007]理想的正方形 二维单调队列

    题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=1047 我们对每矩阵的一列维护一个大小为$n$的单调队列,队中元素为矩阵中元素.然后扫描每一 ...

随机推荐

  1. DOM对象,控制HTML元素(1)

    1:getElementsByName(name)方法 它是通过元素的name属性来查询元素,而不是通过id属性.getElementById()方法是通过元素的id属性来获取元素的. 注意: 该方法 ...

  2. SpringBoot集成Redis来实现缓存技术方案

    概述 在我们的日常项目开发过程中缓存是无处不在的,因为它可以极大的提高系统的访问速度,关于缓存的框架也种类繁多,今天主要介绍的是使用现在非常流行的NoSQL数据库(Redis)来实现我们的缓存需求. ...

  3. [Apple开发者帐户帮助]九、参考(5)支持的功能(tvOS)

    tvOS应用程序可用的功能取决于您的程序成员身份. 能力 ADP 企业 Apple开发者 应用程序组 相关域名   背景模式 数据保护 游戏中心     游戏控制器 HomeKit iCloud:Cl ...

  4. [Swift通天遁地]二、表格表单-(6)创建美观的表格弹性下拉刷新效果

    ★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★➤微信公众号:山青咏芝(shanqingyongzhi)➤博客园地址:山青咏芝(https://www.cnblogs. ...

  5. [Swift通天遁地]五、高级扩展-(9)颜色、设备、UserDefaults、URL等扩展方法

    ★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★➤微信公众号:山青咏芝(shanqingyongzhi)➤博客园地址:山青咏芝(https://www.cnblogs. ...

  6. [Swift通天遁地]七、数据与安全-(2)对XML和HTML文档的快速解析

    ★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★➤微信公众号:山青咏芝(shanqingyongzhi)➤博客园地址:山青咏芝(https://www.cnblogs. ...

  7. Java并发编程系列之Semaphore详解

    简单介绍 我们以饭店为例,假设饭店只有三个座位,一开始三个座位都是空的.这时如果同时来了三个客人,服务员人允许他们进去用餐,然后对外说暂无座位.后来的客人必须在门口等待,直到有客人离开.这时,如果有一 ...

  8. 【BZOJ3205_洛谷3638】[APIO2013]机器人(动态规划)

    题目: 洛谷3638 分析: 卡了一天的神题--(OrzJumpmelon) 首先预处理出从点\(p\)向\(d\)方向出发最终能到达的点\(nxt[p][d]\).这个可以直接记忆化搜索解决.如果出 ...

  9. docker容器如何安装vim

    mv /etc/apt/sources.list /etc/apt/sources.list.bak && \     echo "deb http://mirrors.16 ...

  10. struts2.1.6存在中文乱码的bug

    如题,后续版本中已解决:可以通过添加filter的方式解决.