import java.util.*; /** * NC304 最大子矩阵 * @author d3y1 */ public class Solution { /** * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可 * * * @param matrix int整型ArrayList<ArrayList<>> * @return int整型 */ public int getMaxMatrix (ArrayList<ArrayList<Integer>> matrix) { return solution1(matrix); // return solution2(matrix); } /** * 动态规划 * * 相似 -> NC302 环形数组的连续子数组最大和 * * dp[k] 表示矩阵从第i行到第j行且以第k列为底(最右列)的子矩阵的最大和 * sum[k]表示矩阵从第i行到第j行中第k列的元素和 * * { dp[k-1] + sum[k] , dp[k-1] > 0 && 1<=i<=n && i<=j<=n && 1<=k<=n * dp[k] = { * { sum[k] , dp[k-1] <= 0 && 1<=i<=n && i<=j<=n && 1<=k<=n * * k=2 * | * 0 -2 -7 0 * i=2 -> 9 2 -6 2 * -4 1 -4 1 * j=4 -> -1 8 0 -2 * sum[k] 4 11 -10 1 * dp[k] 4 15 5 6 * * => result = Math.max(result, dp[k]) = dp[2] = 15 * * @param matrix * @return */ private int solution1(ArrayList<ArrayList<Integer>> matrix){ int n = matrix.size(); int[] sum,dp; int result = Integer.MIN_VALUE; for(int i=1; i<=n; i++){ sum = new int[n+1]; dp = new int[n+1]; for(int j=i; j<=n; j++){ for(int k=1; k<=n; k++){ sum[k] += matrix.get(j-1).get(k-1); if(dp[k-1] > 0){ dp[k] = dp[k-1] + sum[k]; }else{ dp[k] = sum[k]; } result = Math.max(result, dp[k]); } } } return result; } /** * 动态规划 * * dp[i][j]表示从矩阵左上角(1,1)到以位置(i,j)(第i行第j列)为右下角的子矩阵的和 * * { matrix.get(i-1).get(j-1) , i==1 && j==1 * dp[i][j] = { dp[i][j-1] + matrix.get(i-1).get(j-1) , i==1 && j>1 * { dp[i-1][j] + matrix.get(i-1).get(j-1) , i>1 && j==1 * { dp[i][j-1] + dp[i-1][j] - dp[i-1][j-1] + matrix.get(i-1).get(j-1) , i>1 && j>1 * * * sum表示矩阵中以位置(i,j)(第i行第j列)为左上角且以位置(k,m)(第k行第m列)为右下角的子矩阵的和 * * sum = dp[k][m] - dp[k][j-1] - dp[i-1][m] + dp[i-1][j-1] , 1<=i<=n && 1<=j<=n && i<=k<=n && j<=m<=n * * @param matrix * @return */ private int solution2(ArrayList<ArrayList<Integer>> matrix){ int n = matrix.size(); int[][] dp = new int[n+1][n+1]; for(int i=1; i<=n; i++){ for(int j=1; j<=n; j++){ if(i==1 && j==1){ dp[i][j] = matrix.get(i-1).get(j-1); }else if(i==1 && j>1){ dp[i][j] = dp[i][j-1] + matrix.get(i-1).get(j-1); }else if(i>1 && j==1){ dp[i][j] = dp[i-1][j] + matrix.get(i-1).get(j-1); }else{ dp[i][j] = dp[i][j-1] + dp[i-1][j] - dp[i-1][j-1] + matrix.get(i-1).get(j-1); } } } int result = Integer.MIN_VALUE; int sum; for(int i=1; i<=n; i++){ for(int j=1; j<=n; j++){ for(int k=i; k<=n; k++){ for(int m=j; m<=n; m++){ sum = dp[k][m] - dp[k][j-1] - dp[i-1][m] + dp[i-1][j-1]; result = Math.max(result, sum); } } } } return result; } }