zoukankan      html  css  js  c++  java
  • P2216 [HAOI2007]理想的正方形

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

    很显然我们可以用DP水掉这道题的大多数分。设f_max[i][j][k]表示以坐标[i,j]为右下角,边长为k的正方形的最大值,最小值同理再设一个。

    因为每次处理的时候正方形边长+1,我们考虑压缩掉边长这个维度。也就是说,先预处理上边长为1的正方形(蛤蛤蛤就是输入啦),然后进行k-1次矩阵递推,得到的数据就一定是以k为边长的正方形的大小啦~

    最后水过了

    #include<cstdio>
    #include<cstring>
    #include<iostream>
    #define INF 0x7777777f
    using namespace std;
    int n,m,k,ans=INF,mp[1010][1010],f_max[1010][1010],f_min[1010][1010];
    inline int max(int x,int y){return x>y?x:y;}
    inline int min(int x,int y){return x<y?x:y;}
    inline int read(){
       int s=0,w=1;
       char ch=getchar();
       while(ch<'0'||ch>'9'){if(ch=='-')w=-1;ch=getchar();}
       while(ch>='0'&&ch<='9') s=s*10+ch-'0',ch=getchar();
       return s*w;
    }
    int main(){
        scanf("%d%d%d",&n,&m,&k);
        for(register int i=1;i<=n;++i){
            for(register int j=1;j<=m;++j){
                mp[i][j]=read();
                f_max[i][j]=mp[i][j];//init 
                f_min[i][j]=mp[i][j];
            }
        }
        for(register int l=2;l<=k;++l){
            for(register int i=n;i>=l;i--){
                for(register int j=m;j>=l;j--){
                    f_max[i][j]=max(mp[i][j],max(f_max[i-1][j],max(f_max[i][j-1],f_max[i-1][j-1])));
                    f_min[i][j]=min(mp[i][j],min(f_min[i-1][j],min(f_min[i][j-1],f_min[i-1][j-1])));
                }
            }       
        }
        for(register int i=k;i<=n;++i){
            for(register int j=k;j<=m;++j){
                ans=min(ans,f_max[i][j]-f_min[i][j]);
            }
        }
        printf("%d
    ",ans);
        return 0;
    } 
    View Code
  • 相关阅读:
    Hui之组件大全
    程序员交流学习平台
    PHP 常用框架
    常用浏览器
    设计必备工具、平台
    文档必备工具
    开发必备工具
    工作必备工具
    源码托管平台、软件
    前端常用框架
  • 原文地址:https://www.cnblogs.com/shikeyu/p/12687239.html
Copyright © 2011-2022 走看看