2.類似的題 zoj problem set - 1074 :
給定乙個n*m的矩陣a,求a中的乙個非空子矩陣,使這個子矩陣中的元素和最大。
其中,a的子矩陣指在a中行和列均連續的一塊。
樣例說明
取最後一列,和為10。
資料規模和約定
對於100%的資料,1< =n, m< =500,a中每個元素的絕對值不超過5000。
輸入的第一行包含兩個整數n, m,分別表示矩陣a的行數和列數。
接下來n行,每行m個整數,表示矩陣a。
輸出一行,包含乙個整數,表示a中最大的子矩陣中的元素和。
33-
1-43
34-1
-5-2
8
10
題意很簡單,就是求子矩陣中元素和最大為多少,第一想法就是二維的字首和處理,a是原陣列,sum是對應的字首和陣列,表示從左上角到當前位置的矩陣內的元素和。
for
(int i=
1; i<=n; i++
)}
有了字首和就可以通過其來計算子矩陣的和,可是接下來怎麼做呢,直接列舉起點和終點嗎?
int res =
-inf;
for(
int x1=
0; x1}}
顯然,這樣的演算法寫完是o(n
4)
o(n^4)
o(n4
)的時間複雜度,看看資料應該是過不了的。
那能不能減少一重迴圈,降到o(n
3)
o(n^3)
o(n3
),發現是可行的。
我們回顧一下求一維陣列的區間和最大,還是先算的字首和陣列sum。
貪心:遍歷 sum [ r ] ,每一步都取最小的 sum[ l-1 ] , 求差值更新res的值。
int min =
0, res =
-inf;
for(
int i=
1; i<=n; i++
)
那麼在這個想法下我們可不可以把二維計算的過程降到一維的情況下,在一維的情況下計算各區間的和?轉化一下,這樣就可以減少一重迴圈。
我們可以先求每一列的一維區間和,這樣子我們就可以直接枚舉子矩陣的左上端點和右下端點的行就可以了,剩餘就相當於遍歷所有列,按照上面求一維區間和最大的方法計算即可。當然你也可以求每一行的一維區間和再上面思路對應做(相當於旋轉了一下矩陣而已嘛)。(可能講的不太明白,可以看看**理解一下)
#include
#include
using
namespace std;
const
int max_n =
500;
const
int max_m =
500;
const
int inf =
100000
;//輸入
int n, m;
int a[max_n +1]
[max_m +1]
;int f[max_n +1]
[max_m +1]
;//求一列的字首和
int sum[max_n +1]
;//求一維最大區間和的方式
intmain()
}for
(int i =
1; i <= n; i++)}
int res =
-inf;
for(
int i =
0; i < n; i++
)//求得以i+1行的點為左上端點的情況下子矩陣最大為多少
int min =0;
for(
int k =
1; k <= m; k++
)//求一維最大區間和
//迴圈更新答案}}
printf
("%d\n"
, res)
;return0;
}
進行列舉的迴圈可以寫的更好理解一點
迴圈的變數直接對應兩個端點的行
#include
#include
using
namespace std;
const
int max_n =
500;
const
int max_m =
500;
const
int inf =
100000
;//輸入
int n, m;
int a[max_n +1]
[max_m +1]
;int f[max_n +1]
[max_m +1]
;//求一列的字首和
int sum[max_n +1]
;//求一維最大區間和的方式
intmain()
}for
(int i =
1; i <= n; i++)}
int res =
-inf;
//列舉左上端點和右下端點的行號,i對應左上端點,j對應右下端點
for(
int i =
1; i <= n; i++
)int min =0;
for(
int k =
1; k <= m; k++
)//求一維最大區間和 }}
printf
("%d\n"
, res)
;return0;
}
當然也可以dp做法,思路類似,也是計算遞推式子。 藍橋杯 最大子陣
給定乙個nxm的矩陣a,求a中的乙個非空子矩陣,使這個子矩陣中的元素和最大。其中,a的子矩陣指在a中行和列均連續的一塊。輸入格式 輸入的第一行包含兩個整數n,m,分別表示矩陣a的行數和列數。接下來n行,每行m個整數,表示矩陣a。輸出格式 輸出一行,包含乙個整數,表示a中最大的子矩陣中的元素和。3 3...
藍橋杯 最大子陣 dp
歷屆試題 最大子陣 時間限制 1.0s 記憶體限制 256.0mb 問題描述 給定乙個n m的矩陣a,求a中的乙個非空子矩陣,使這個子矩陣中的元素和最大。其中,a的子矩陣指在a中行和列均連續的一塊。輸入格式 輸入的第一行包含兩個整數n,m,分別表示矩陣a的行數和列數。接下來n行,每行m個整數,表示矩...
藍橋杯 歷屆試題 最大子陣
歷屆試題 最大子陣 時間限制 1.0s 記憶體限制 256.0mb 問題描述 給定乙個n m的矩陣a,求a中的乙個非空子矩陣,使這個子矩陣中的元素和最大。其中,a的子矩陣指在a中行和列均連續的一塊。輸入格式 輸入的第一行包含兩個整數n,m,分別表示矩陣a的行數和列數。接下來n行,每行m個整數,表示矩...