题意:给定一个整形n,输入一个n*n矩阵,求该矩阵中和最大的子矩阵数值和。
分析:最大字段和的问题,将二维数组转化为一维数组,枚举所有子矩阵情况,获取最大值。
代码:
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner s = new Scanner(System.in);
int[][] arr;
int n = 0;
while (s.hasNext()) {
n = s.nextInt();
if (n == 0)
break;
arr = new int[n][n];
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
arr[i][j] = s.nextInt();
}
}
System.out.println(getMaxRect(arr));
}
}
private static int getMaxRect(int[][] arr) {
int maxSum = Integer.MIN_VALUE;
int n = arr.length;
int[] temp;
for (int start = 0; start < n - 1; start ++) {
for (int end = 1; end < n; end ++) {
//将多列看为一列
temp = new int[n];
//对于每一行
for (int r = 0; r < n; r ++)
//将改行从start列到end列的值相加,存入temp数组中
for (int c = start; c <= end; c ++)
temp[r] += arr[r][c];
int sum = 0;
//最大字段和的问题
//求以r行结尾,能得到的最大值(为r-1能得到的最大值加上r行的值,r行的值,二者中的大者)
//即动态转移方程:dp[r] = max(dp[r - 1] + temp[r], temp[r]), dp[r]表示以r结尾的最大字段和
for (int r = 0; r < n; r ++) {
if (sum + temp[r] > 0)
sum += temp[r];
else
sum = 0;
//更新最大值
if (sum > maxSum)
maxSum = sum;
}
}
}
return maxSum;
}
}