[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 }
原文地址:https://www.cnblogs.com/HHshy/p/6065265.html