最大子矩阵问题实例解析
问题: 0 -2 -7 0 9 2 -6 2 -4 1 -4 1 -1 8 0 -2 拥有最大和的子矩阵为: 9 2 -4 1 -1 8 其和为15。 0 -2 -7 0 9 2 -6 2 或者 9 2 -6 2 -4 1 -4 1 或者 -4 1 -4 1 -1 8 0 -2 在每一种情况里(我们这里有三种),我们还要找出一个最大的子矩阵,当然,这只是一种情况的最大子矩阵(局部最大),不一定是global最大。但是,如果我们知道每一种情况的最大,要找出global最大,那就小菜一碟儿了。 Java实现示例: public int maxSubsequence(int[] array) { if (array.length == 0) { return 0; } int max = Integer.MIN_VALUE; int[] maxSub = new int[array.length]; maxSub[0] = array[0]; for (int i = 1; i < array.length; i++) { maxSub[i] = (maxSub[i-1] > 0) ? (maxSub[i-1] + array[i]) : array[i]; if (max < maxSub[i]) { max = maxSub[i]; } } return max; } 但是,原始矩阵可以是二维的。假设原始矩阵是一个3 * n 的矩阵,那么它的子矩阵可以是 1 * k,2 * k,3 * k,(1 <= k <= n)。 如果是1*K,这里有3种情况:子矩阵在第一行,子矩阵在第二行,子矩阵在第三行。如果是 2 * k,这里有两种情况,子矩阵在第一、二行,子矩阵在第二、三行。如果是3 * k,只有一种情况。 9 2 -6 2 -4 1 -4 1 -1 8 0 -2 里找最大的子矩阵。 int[][] total = matrix; for (int i = 1; i < matrix[0].length; i++) { for (int j = 0; j < matrix.length; j++) { total[i][j] += total[i-1][j]; } } 如果我们要求第 i 行到第 j 行之间上下值的和,我们可以通过total[j][k] - total[i-1][k] 得到,k 的范围从1 到 matrix[0].length - 1。 public int subMaxMatrix(int[][] matrix) { int[][] total = matrix; for (int i = 1; i < matrix[0].length; i++) { for (int j = 0; j < matrix.length; j++) { total[i][j] += total[i-1][j]; } } int maximum = Integer.MIN_VALUE; for (int i = 0; i < matrix.length; i++) { for (int j = i; j < matrix.length; j++) { //result 保存的是从 i 行 到第 j 行 所对应的矩阵上下值的和 int[] result = new int[matrix[0].length]; for (int f = 0; f < matrix[0].length; f++) { if (i == 0) { result[f] = total[j][f]; } else { result[f] = total[j][f] - total[i - 1][f]; } } int maximal = maxSubsequence(result); if (maximal > maximum) { maximum = maximal; } } } return maximum; } C语言相关的实现 题目 题目描述: 0 -2 -7 0 9 2 -6 2 -4 1 -4 1 -1 8 0 -2 9 2 -4 1 -1 8
#include <stdio.h> #include <stdlib.h> int main(void) { int i,j,h,k,n,max,sum,cur,matrix[101][101]; while (scanf("%d",&n) != EOF) { // 初始化接收矩阵 for (i = 0; i < n; i ++) { for (j = 0; j < n; j ++) scanf("%d",*(matrix + i) + j); } // 动态规划(类似于一维数组连续最大子序列和) max = matrix[0][0]; for (i = 0; i < n; i ++) { // i,j确定上下界 for (j = i; j < n; j ++) { // 初始化 for (k = i,sum = 0; k <= j; k ++) sum += matrix[k][0]; if (sum > max) max = sum; for (h = 1; h < n; h ++) { for (k = i,cur = 0; k <= j; k ++) cur += matrix[k][h]; if (sum >= 0) sum += cur; else sum = cur; if (sum > max) max = sum; } } } printf("%dn",max); } return 0; } (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |