题目
最大子矩阵和问题。给定m行n列的整数矩阵A,求矩阵A的一个子矩阵,使其元素之和最大。
输入格式:
第一行输入矩阵行数m和列数n(1≤m≤100,1≤n≤100),再依次输入m×n个整数。
输出格式:
输出第一行为最大子矩阵各元素之和,第二行为子矩阵在整个矩阵中行序号范围与列序号范围。
输入样例1:
5 6
60 3 -65 -92 32 -70
-41 14 -38 54 2 29
69 88 54 -77 -46 -49
97 -32 44 29 60 64
49 -48 -96 59 -52 25
输出样例1:
输出第一行321表示子矩阵各元素之和,输出第二行2 4 1 6表示子矩阵的行序号从2到4,列序号从1到6
321
2 4 1 6
可运行代码
#include<bits/stdc++.h>
using namespace std;
const int N=1100;
int dp[N][N];
int main(){
//第一步:加每一列的前缀和
int n,m,result=-0x3f3f3f3f;
cin>>n>>m;
for(int i=1;i<=n;i++){
for(int j=1;j<=m;j++){
int t;
cin>>t;
dp[i][j] = dp[i-1][j]+t;
}
}
//第二步,根据每一列的前缀和计算子矩阵的最大和
int x1,y1,x2,y2;
for(int i=1;i<=n;i++){ //下边界
for(int j=1;j<=i;j++){ //上边界
int yy=1; //左边界
int temp=0;
for(int k=1;k<=m;k++){ //右边界
temp += dp[i][k]-dp[j-1][k] ; //加每一列的前缀和
if(temp>result){ //大于最大值,赋值
result=temp;
x1=j, x2=i, y1=yy, y2=k;
}else if(temp<0){ //小于0,左边界移动到k+1,temp重新从k+1加每一列的前缀和
temp=0; // 小于0后重新赋值
yy=k+1;
}
}
}
}
printf("%d\n%d %d %d %d",result,x1,x2,y1,y2);
return 0;
}
第一步:
第二步
yy控制左边界,k控制右边界,j 控制上边界 , i 控制下边界