• [VijosP1764]Dual Matrices 题解


    题目大意:

      一个N行M列的二维矩阵,矩阵的每个位置上是一个绝对值不超过1000的整数。你需要找到两个不相交的A*B的连续子矩形,使得这两个矩形包含的元素之和尽量大。

    思路:

      预处理,n2时间算出每个点左上方的数的总和,如此可以O(1)算出一个目标矩阵的和。再预处理出自底向下到每行最大的子矩阵、自右向左到每列最大的子矩阵,再n2枚举一个子矩阵,计算与其右方和下方最大的子矩阵的和即可出答案。

      至于无解虽然数据貌似没有,但只需考虑两个横放或竖放或一横一竖放可不可以即可。

      横竖的处理细节挺多,要dxx。

    代码:

     1 #include<cstdio>
     2 const int M=1001;
     3 int n,m,x,y,i,j,ans=-2000000000,sum[M][M],lmax[M],rmax[M];
     4 
     5 int ju(int i,int j,int x,int y){ return sum[i+x-1][j]-sum[i-1][j]-sum[i+x-1][j-y]+sum[i-1][j-y]; }
     6 
     7 void line(int n,int m,int x,int y)
     8 {
     9     int i,j,t;
    10     for (i=n-x+1;i;--i)
    11     {
    12         if (lmax[i]<lmax[i+1]) lmax[i]=lmax[i+1];
    13         for (j=y;j<=m;++j)
    14         {
    15             t=ju(i,j,x,y);
    16             if (t>lmax[i]) lmax[i]=t;
    17         }
    18     }
    19 }
    20 
    21 void row(int n,int m,int x,int y)
    22 {
    23     int i,j,t;
    24     for (i=n-y+1;i;--i)
    25     {
    26         if (rmax[i]<rmax[i+1]) rmax[i]=rmax[i+1];
    27         for (j=1;j+x<m+2;++j)
    28         {
    29             t=ju(j,i+y-1,x,y);
    30             if (t>rmax[i]) rmax[i]=t;
    31         }
    32     }
    33 }
    34 
    35 void cal(int x,int y)
    36 {
    37     int i,j,t;
    38     for (i=1;i+x<n+2;++i)
    39         for (j=y;j<=m;++j)
    40         {
    41             t=ju(i,j,x,y);
    42             if (i+x<=n && t+lmax[i+x]>ans) ans=t+lmax[i+x];
    43             if (j<m && t+rmax[j+1]>ans) ans=t+rmax[j+1];
    44         }
    45 }
    46 
    47 int main()
    48 {
    49     scanf("%d%d%d%d",&n,&m,&x,&y);
    50     for (i=1;i<=n;++i)
    51         for (j=1;j<=m;++j) scanf("%d",&sum[i][j]);
    52     for (i=1;i<=n;++i)
    53         for (j=1;j<=m;++j) sum[i][j]=sum[i][j-1]+sum[i-1][j]+sum[i][j]-sum[i-1][j-1];
    54     for (i=1;i<n+2;++i) lmax[i]=ans;
    55     for (i=1;i<m+2;++i) rmax[i]=ans;
    56     line(n,m,x,y),line(n,m,y,x);
    57     row(m,n,x,y),row(m,n,y,x);
    58     cal(x,y),cal(y,x);
    59     if ((x+x>n || y>m) && (y+y>n || x>m) && 
    60         (x+x>m || y>n) && (x+y>n || x>m) && 
    61         (x+y>m || x>n) && (x+y>n || y>m) && (x+y>m || x>n)) puts("Impossible");
    62     else printf("%d
    ",ans);
    63     return 0;
    64 }
  • 相关阅读:
    Windows安装和使用zookeeper
    Maven安装以及环境配置(Windows)
    greenplum下载地址
    Install Greenplum OSS on Ubuntu
    MySQL主从复制与主主复制
    HADOOP+SPARK+ZOOKEEPER+HBASE+HIVE集群搭建(转)
    kafka实战
    rtl8723 2个 wlan
    wpa supplicant 移植
    wireless tool 移植
  • 原文地址:https://www.cnblogs.com/HHshy/p/6065265.html
Copyright © 2020-2023  润新知