1. 程式人生 > >P1719 最大加權矩形

P1719 最大加權矩形

png 計算 http 最大 重點 pan 大小 std 列數

P1719 最大加權矩形

題目描述

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

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

0 –2 –7 0 在左下角: 9 2

9 2 –6 2 -4 1

-4 1 –4 1 -1 8

-1 8 0 –2 和為15

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

輸入輸出格式

輸入格式:

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

輸出格式:

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

輸入輸出樣例

輸入樣例#1: 復制
4
0 –2 –7 0
 9 2 –6 2
-4 1 –4  1 
–1 8  0 –2
輸出樣例#1: 復制
15

說明

n<=120

洛谷題解:

本題如果每次找左上和右下坐標,復雜度為O(N^4),會超時。所以采用降維的思想。

枚舉上下邊界,然後用一個一維數組b表示每列在上下界之間的數字之和,這樣就轉化為一維的問題。復雜度O(N^3)

枚舉上下邊界,然後枚舉列數,沒列的值可以直接用前綴和來減就好了。

技術分享

動態規劃+枚舉,重點在把二維的東西變成一維(同樓下觀點)。

把一行所在的值加在一起,作為一個值;枚舉每一列就行了。

 1 #include<iostream>
 2 using namespace std;
 3 int n,a[121][121],rowsum[121][121],area,ans;
 4 void read()
 5 {
 6     int i,j,k;
7 cin>>n; 8 for(i=1; i<=n; i++) 9 for(j=1; j<=n; j++) 10 cin>>a[i][j]; 11 for(i=1; i<=n; i++) 12 for(j=1; j<=n; j++) 13 rowsum[i][j]=rowsum[i][j-1]+a[i][j]; 14 for(i=1; i<=n; i++) 15 for(j=i; j<=n; j++) 16 { 17 area=0; 18 for(k=1; k<=n; k++) 19 { 20 area+=rowsum[k][j]-rowsum[k][i-1]; 21 if(area>ans) ans=area; 22 if(area<0) area=0; 23 } 24 } 25 cout<<ans; 26 return; 27 } 28 int main() 29 { 30 read(); 31 return 0; 32 }

P1719 最大加權矩形