http://acm.hdu.edu.cn/showproblem.php?pid=1559
这题相对上一题来说多了个限制条件,矩阵大小要是x*y的,这样的话倒更简单,只需计算出连续的x行,连续的y列和最大和即可,纵列和的求解用到了压缩的思想,就是把连续的x行上的同一列的数都相加存储在一个数组列对应的的下标元素里面
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 #include<stdio.h> 2 #include<string.h> 3 int a[1001][1001],n,m,x,y; 4 int maxx(int *b,int k) 5 { 6 int i,max=0,sum[11111]; 7 for(i=0;i<k;i++) 8 { 9 if(i<y) 10 { 11 max+=b[i]; 12 sum[y-1]=max; 13 continue; 14 } 15 sum[i]=sum[i-1]-b[i-y]+b[i]; 16 if(sum[i]>max)max=sum[i]; 17 } 18 return max;//计算不同的行之间的相同的列之和的最大和,即一个矩阵 19 } 20 int maxpp() 21 { 22 int b[11111],i,j,sum=-999999,max,k; 23 for(i=0;i<n-x;i++)//将所有的行枚举一遍 24 { 25 memset(b,0,sizeof(b)); 26 for(j=i;j<i+x;j++)//这里仿造最大字段和的写法 27 { 28 for(k=0;k<m;k++) 29 { 30 b[k]+=a[j][k];//b[k]为纵向的列的和,这样每个b[k]对应的行,列就都一样了,就可以进行相加比较了 31 } 32 } 33 max=maxx(b,k); 34 if(sum<max)sum=max;//这三行之所以放在同一的循环里面就是为了 每一纵列都能进行一次取最大值 35 } 36 return sum; 37 } 38 int main() 39 { 40 int i,j,t; 41 scanf("%d",&t); 42 while(t--) 43 { 44 scanf("%d%d%d%d",&n,&m,&x,&y); 45 for(i=0;i<n;i++) 46 for(j=0;j<m;j++) 47 scanf("%d",&a[i][j]); 48 printf("%d ",maxpp()); 49 } 50 return 0; 51 }