23日目126最大合計(2次元プレフィックス合計)

126.最大額

整数を含む2次元行列が与えられた場合、サブ長方形は、1 * 1配列全体の中でサイズ以上の連続したサブ配列です。

長方形の合計は、長方形内のすべての要素の合計です。

この問題では、合計が最大のサブ長方形は最大サブ長方形と呼ばれます。

たとえば、次の配列:

0 -2 -7 0
9 2 -6 2
-4 1 -4 1
-1 8 0 -2

最大のサブ長方形は次のとおりです。

9 2
-4 1
-1 8

最大合計は15です。

入力フォーマット
入力にはN ∗ NN * Nが含まれますNNの整数配列

最初の行に整数NNのみを入力しますNは、正方形の2次元配列のサイズを表します。

2行目から、スペースと改行で区切ってN 2 N ^ 2と入力します。N2つの整数、2次元配列ではN 2 N ^ 2N2つの要素、入力シーケンスは2次元配列の最初の行から始まり、行ごとに入力され、同じ行のデータが左から右に1つずつ入力されます。

配列内の数値は[-127,127]の範囲のままになります。

出力形式
最大のサブ長方形の合計を表す整数を出力します

データ範囲
1≤N≤1001≤N≤1001N。1つの0 0
入力サンプル:

0 -2 -7 0
9 2 -6 2
-4 1 -4 1
-1 8 0 -2

サンプル出力:

15

アイデア

位置s[i][j]から(0,0)位置の(i,j)すべての要素まで表し、s[i][j]次のように計算されたとします。
ここに画像の説明を挿入
次に(x1, y1)、左上隅、(x2, y2):需要のサブマトリックス右下隅、および以下に示すようにどのようになりますか?
ここに画像の説明を挿入
2次元配列が前に付けられますそして、すべての部分行列を列挙し、最大値を見つけるだけで済みます。

Javaコード

import java.util.Scanner;

public class Main {
    
    
    public static void main(String[] args) {
    
    
        Scanner scanner = new Scanner(System.in);
        int n = scanner.nextInt();
        int[][] arr = new int[n + 1][n + 1];//避免下标转换
        int[][] s = new int[n + 1][n + 1];//前缀和数组
        //读取数据
        for(int i = 1;i <= n ;i++){
    
    
            for(int j = 1;j <= n;j++){
    
    
                arr[i][j] = scanner.nextInt();
            }
        }

        //计算二维前缀和s[i][j] = s[i-1][j] + s[i][j-1] - s[i-1][j-1] + arr[i][j]
        //这里就显示了我们将下标设置为成1开始的优势了,i - 1最小也是0,而s[0][j]默认都是0,公式中加上0也没事
        //但如果下标从0开始,则s[i-1][j]中的i-1可能会下标越界,需要我们特判,增加麻烦
        for(int i = 1;i <= n;i++){
    
    
            for(int j = 1;j <= n;j++){
    
    
                s[i][j] = s[i-1][j] + s[i][j-1] - s[i-1][j-1] + arr[i][j];
            }
        }

        int res = Integer.MIN_VALUE;
        for(int x2 = 1;x2 <= n;x2++){
    
    
            for(int y2 = 1;y2 <= n;y2++){
    
    //枚举子矩阵的右下角(x2,y2)
                for(int x1 = 1;x1 <= x2;x1++){
    
    
                    for(int y1 = 1;y1 <= y2;y1++){
    
    //枚举子矩阵的左上角(x1,y1) 注for中条件为: (x1,y1)<= (x2,y2)
                        res = Math.max(res,s[x2][y2] - s[x1 -1][y2] - s[x2][y1 - 1] + s[x1 - 1][y1 - 1]);
                    }
                }
            }
        }
        System.out.println(res);
    }
}

ここに画像の説明を挿入

おすすめ

転載: blog.csdn.net/YouMing_Li/article/details/113917601