蓝桥杯 最大子阵

问题描述
  给定一个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。

题目大意:

  1. 求连续行、列的子矩阵的最大元素和。
  2. 由于行、列必须是连续的,所以可以求出每一列前n行的和,前缀和
  3. 然后再枚举一个 行的开始和结束,然后再用最大字段和求出最大和
    最大连续子序列和的二维版
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);
	}
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章