子矩阵最大累加和

描述 给定一个由整数组成二维矩阵(r*c),现在需要找出它的一个子矩阵,使得这个子矩阵内的所有元素之和最
大,并把这个子矩阵称为最大子矩阵。例子: 0 -2 -7 0 9 2 -6 2 -4 1 -4 1 -1 8 0 -2 其最大子矩阵
为: 9 2 -4 1 -1 8 其元素总和为15。 输入 第一行输入一个整数n(0

第一,如何更简单地计算出一个子矩阵的和?

先考虑子问题行数固定的矩阵(i=2,j=4)k=1~4里的矩阵哪个累加和最大,把所有的列相加得到一个一维数据,求一维数据的最大累加和。在数据录入的时候,就应该是num[i]+=num[i-1],这样,要计算从j到i的数据之和,直接num[i]-num[j-1]就能直接得出了

第二,如何求数组的最大累加和

如果某段数据累加和出现负数那么这段数据一定不是最大累加和数据段的一部分,从第一个数开始累加如果tempmax出现负数,tempmax置为0,重新开始累加。max记录最大的tempmax

第三,如何遍历出所有可能的子矩阵?

这里可以使用三个变量i,j,k来遍历。如果一个矩阵大小是M*N的,那么可以使i从0到M,再使j从每一个i到M,这样就把行方向给遍历完了。再考虑列方向,直接在每一种i,j组合下,进行0到N的遍历,那么这样就等于是把所有子矩阵的情形给遍历完了。

子矩阵最大累加和_第1张图片

代码如下:
 


public class 最大子矩阵 {

	private static int num[][] = new int[101][101];
	private static int n;
	private static Scanner input = new Scanner(System.in);

	public static void main(String[] args) {
		getMax();
	}
	public static int getMax() {

		n = input.nextInt();
		n = n - 1;
		while (n  >= 0) {
			int r, c;
			r = input.nextInt();
			c = input.nextInt();
			int i, j, k;
			initArr(r,c,num);
			for (i = 1; i <= r; i++)
				for (j = 1; j <= c; j++) {
					num[i][j] = input.nextInt();
					num[i][j] += num[i - 1][j];
				}
			int temp = 0;
			int max = num[1][1];
			int tempmax;
			for (i = 1; i <= r; i++) {
				for (j = i; j <= r; j++) {
					tempmax = 0;
					for (k = 1; k <= c; k++) {
						temp = num[j][k] - num[i - 1][k];
						tempmax = (tempmax >= 0 ? tempmax : 0) + temp;
						max = tempmax > max ? tempmax : max;
					}
				}
			}
			System.out.println(max);
		}
		return 0;
	}

	public static  void initArr(int r, int c, int[][] a) {
		for (int i = 0; i < r; i++) {
			for (int j = 0; j < c; j++) {
				a[i][j] = 0;
			}
		}
	}

}

 

你可能感兴趣的:(子矩阵最大累加和)