最大加權矩形

风掣凧浮發表於2024-11-16

最大加權矩形

題目描述

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

校長先給他們一個 \(n\times 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 \leq n\le 120\)






解題

今天我怎麼就寫得這麼順利呢?੭ ˙ᗜ˙ ੭

本題計算矩陣和,僅需要先錨定矩形右下點座標,再減去左邊部分和上邊部分,最後加上(左邊和上邊重合的)左上部分即可。

0 -2 -7 0
​ __9 __ 2 -6 2
-4 1 -4 1
__-1 __ 8 0 -2

為計算方便,可先計算字首和(由題設矩陣 左上角 和 當前位置構成的矩陣和),如圖。

0 -2 -9 -9
9 9 -4 -2
5 6 -11 -8
4 13 -4 -3

#include<stdio.h>

//題設陣列     , 字首和陣列
int a[130][130], b[130][130];
int n;

int main()
{
    //輸入
    scanf("%d", &n);
    for (int i = 1; i <= n; i++)
    {
        for (int j = 1; j <= n; j++)
        {
            scanf("%d", &a[i][j]);
        }
    }

    //計算字首和
    for (int i = 1; i <=n; i++)
    {
        for (int j = 1; j <= n; j++)
        {
            int sum = 0;
            for (int k = 1; k <= i; k++)
            {
                sum += a[k][j];
            }
            b[i][j] = b[i][j - 1] + sum;
        }
    }

    //計算
    int ans = 0;
    for (int i = 1; i <= n; i++)//i和j表示矩形的右下角頂點座標
    {
        for (int j = 1; j <= n; j++)
        {
            for (int k = 1; k <= i; k++)//k表示矩形的左邊界座標
            {
                for (int l = 1; l <= j; l++)//l表示矩形的上邊界座標
                {
                    //矩形和= 右下點和- 左下點和    - 右上點和    + 左上點和
                    int sum = b[i][j] - b[k - 1][j] - b[i][l - 1] + b[k - 1][l - 1];
                    //更新ans為最大
                    ans = (ans > sum) ? ans : sum;
                }
            }
        }
    }
    printf("%d\n", ans);
    return 0;
}

相關文章