子矩阵的问题,都可以转化成最大子段和的问题,转换的思想就是把几行合并成一行,求这一行的最大子段和,结果就是子矩阵的最大和了。
#include<stdio.h>
#include<string.h>
int num[1010][1010],dp[1010];
int main(){
int n,m,i,j,t,max,x,y;
scanf("%d",&t);
while(t--){
memset(num,0,sizeof(num));
memset(dp,0,sizeof(dp));
scanf("%d%d%d%d",&n,&m,&x,&y);
for(i=1;i<=n;i++){
for(j=1;j<=m;j++){
scanf("%d",&num[i][j]);
num[i][j]+=num[i-1][j];//把每一列都合并成子段和
}
}
for(max=0,i=x;i<=n;i++){
for(j=1;j<=m;j++){
dp[j]=num[i][j]-num[i-x][j];
dp[j]+=dp[j-1];
if(max<dp[j]-dp[j-y]&&j>=y){
max=dp[j]-dp[j-y];
}
}
}
printf("%d\n",max);
}
return 0;
}