P1719 最大加權矩形

洋洋萱發表於2024-11-16

題目描述

為了更好的備戰 NOIP2013,電腦組的幾個女孩子 LYQ,ZSC,ZHQ 認為,我們不光需要機房,我們還需要運動,於是就決定找校長申請一塊電腦組的課餘運動場地,聽說她們都是電腦組的高手,校長沒有馬上答應他們,而是先給她們出了一道數學題,並且告訴她們:你們能獲得的運動場地的面積就是你們能找到的這個最大的數字。

校長先給他們一個n*n 矩陣。要求矩陣中最大加權矩形,即矩陣的每一個元素都有一權值,權值定義在整數集上。從中找一矩形,矩形大小無限制,是其中包含的所有元素的和最大 。矩陣的每個元素屬於 [-127,127],例如

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

在左下角:

9  2
-4  1
-1  8

和為 15。

幾個女孩子有點犯難了,於是就找到了電腦組精打細算的 HZH,TZY 小朋友幫忙計算,但是遺憾的是他們的答案都不一樣,涉及土地的事情我們可不能含糊,你能幫忙計算出校長所給的矩形中加權和最大的矩形嗎?

輸入格式

第一行:n,接下來是 n 行 n 列的矩陣。

輸出格式

最大矩形(子矩陣)的和。

樣例 #1

樣例輸入 #1

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

樣例輸出 #1

15

提示

1 <=n<=120

Kadane演算法

這是一個經典的求解一維最大子陣列和的演算法,時間複雜度是 O(n)。
過程:我們遍歷所有可能的左右邊界(列),將這兩列之間的所有行元素累加起來形成一個新的陣列。
對於每一個累加的陣列,應用 Kadane 演算法來尋找這個一維陣列的最大子陣列和。

程式碼示例

#include <iostream>
#include <climits>
using namespace std;

// Kadane演算法:求一維陣列中連續子陣列的最大和
int kadane(int arr[], int n) {
    int max_so_far = arr[0];
    int max_ending_here = 0;
    
    for (int i = 0; i < n; i++) {
        max_ending_here += arr[i];
        if (max_ending_here > max_so_far) {
            max_so_far = max_ending_here;
        }
        if (max_ending_here < 0) {
            max_ending_here = 0;
        }
    }
    return max_so_far;
}

// 求最大加權矩形的和,這是主要的求解函式,它透過列舉所有的列對 (left, right),並將這兩列之間的元素累加到 temp 陣列中。然後在 temp 陣列上應用 Kadane 演算法,計算該區域內最大加權矩形的和。
int maxSum(int matrix[][120], int n) {
    int max_sum = INT_MIN;

    // 遍歷所有列對 (left, right)
    for (int left = 0; left < n; ++left) {
        int temp[120] = {0};  // 儲存每列加和後的臨時陣列
        
        for (int right = left; right < n; ++right) {
            // 將從left列到right列的每行元素累加到temp陣列
            for (int i = 0; i < n; ++i) {
                temp[i] += matrix[i][right];
            }
            
            // 在temp陣列上應用Kadane演算法,找出最大和
            int current_max = kadane(temp, n);
            max_sum = max(max_sum, current_max);  // 更新全域性最大和
        }
    }
    
    return max_sum;
}

int main() {
    int n;
    cin >> n;
    
    int matrix[120][120];
    for (int i = 0; i < n; ++i) {
        for (int j = 0; j < n; ++j) {
            cin >> matrix[i][j];
        }
    }

    // 輸出最大加權矩形的和
    cout << maxSum(matrix, n) << endl;

    return 0;
}

相關文章