问题描述
给定一个n*m的矩阵A,求A中的一个非空子矩阵,使这个子矩阵中的元素和最大。
其中,A的子矩阵指在A中行和列均连续的一块。
输入格式
输入的第一行包含两个整数n, m,分别表示矩阵A的行数和列数。
接下来n行,每行m个整数,表示矩阵A。
输出格式
输出一行,包含一个整数,表示A中最大的子矩阵中的元素和。
样例输入
3 3
-1 -4 3
3 4 -1
-5 -2 8
样例输出
10
样例说明
取最后一列,和为10。
数据规模和约定
对于50%的数据,1<=n, m<=50;
对于100%的数据,1<=n, m<=500,A中每个元素的绝对值不超过5000。
题目大意:
- 求连续行、列的子矩阵的最大元素和。
- 由于行、列必须是连续的,所以可以求出每一列前n行的和,前缀和!
- 然后再枚举一个 行的开始和结束,然后再用最大字段和求出最大和
最大连续子序列和的二维版
import java.util.*;
public class Main{
public static int ma(int[] h,int m){//求最大连续子序列和
int a,n=0,max=-10000;
for(int i=0;i<m;i++){//注意这时是求一行中的最大连续子序列和,所以是到m
if(n>0)n+=h[i];
else n=h[i];
max=Math.max(max,n);
}
return max;
}
public static void main(String[] args){
Scanner sc=new Scanner(System.in);
int n=sc.nextInt(),m=sc.nextInt(),ans=-100000,max;
int[][] mp=new int[n][m];
int[] h=new int[m];////存储第i列的前n行的和
for(int i=0;i<n;i++)//读入数据
for(int j=0;j<m;j++)mp[i][j]=sc.nextInt();
for(int i=0;i<n;i++){//i为开始行
for(int j=0;j<m;j++)h[j]=0;//初始化
for(int j=i;j<n;j++){//j为结束行,从i行加到j行
for(int z=0;z<m;z++)h[z]+=mp[j][z];//累加第z列的前n项和
//注意边加就开始求他的最大值,然后动态更新
ans=Math.max(ma(h,m),ans);//每次更新最大值
}
}
System.out.println(ans);
}
}