$bzoj1047-HAOI2007$ 理想正方形 $dp$

  • 题面描述

    • 有一个\(a*b\)的整数组成的矩阵,现请你从中找出一个\(n*n\)的正方形区域,使得该区域所有数中的最大值和最小值的差最小。
  • 输入格式

    • 第一行为\(3\)个整数,分别表示\(a,b,n\)的值第二行至第\(a+1\)行每行为\(b\)个非负整数,表示矩阵中相应位置上的数。每行相邻两数之间用一空格分隔。
    • \(100\%\)的数据\(2\leq a,b\leq 10^3,n\leq a,n\leq b,n\leq 10^3\)
  • 输出格式

    • 仅一个整数,为\(a*b\)矩阵中所有“\(n*n​\)正方形区域中的最大整数和最小整数的差值”的最小值。
  • 题解

    • 利用悬线法思想,先对单行处理,再对列处理。

    • 对单行处理时,用滑动窗口思想,单调队列维护即可。

    • 列处理同理。

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int MAXN=1e3+5;
int n,m,len;
int qmx[MAXN],mxl,mxr;
int qmn[MAXN],mnl,mnr;
int a[MAXN][MAXN];
int lmn[MAXN][MAXN],lmx[MAXN][MAXN];
int ans=1e9;
int main(){
    scanf("%d%d%d",&n,&m,&len);
    for (int i=1;i<=n;i++){
        for (int j=1;j<=m;j++) scanf("%d",&a[i][j]);
    }
    for (int i=1;i<=n;i++){
        mxl=mxr=mnl=mnr=0;
        for (int j=1;j<=m;j++){
            while (mxr>mxl&&a[i][qmx[mxr-1]]<a[i][j]) mxr--;
            qmx[mxr++]=j;
            while (j-qmx[mxl]>=len) mxl++;
            while (mnr>mnl&&a[i][qmn[mnr-1]]>a[i][j]) mnr--;
            qmn[mnr++]=j;
            while (j-qmn[mnl]>=len) mnl++;
            lmx[i][j]=a[i][qmx[mxl]]; lmn[i][j]=a[i][qmn[mnl]];
        }
    }
//  for (int i=1;i<=n;i++){
//      for (int j=1;j<=m;j++) printf("(%d %d) ",lmn[i][j],lmx[i][j]);
//      printf("\n");
//  }
    for (int i=len;i<=m;i++){
        mxl=mxr=mnl=mnr=0;
        for (int j=1;j<=n;j++){
            while (mxr>mxl&&lmx[qmx[mxr-1]][i]<lmx[j][i]) mxr--;
            qmx[mxr++]=j;
            while (j-qmx[mxl]>=len) mxl++;
            while (mnr>mnl&&lmn[qmn[mnr-1]][i]>lmn[j][i]) mnr--;
            qmn[mnr++]=j;
            while (j-qmn[mnl]>=len) mnl++;
            if (j>=len) ans=min(ans,lmx[qmx[mxl]][i]-lmn[qmn[mnl]][i]);
        }
    }
    printf("%d\n",ans);
    return 0;
}

转载于:https://www.cnblogs.com/shjrd-dlb/p/10801055.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值