最大加權矩形
題目描述
為了更好的備戰 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;
}