最大子矩陣和
分析: 我們已經解決了一維的問題(基礎篇中的最大子段和問題),現在變成二維了,我們看看能不能把這個問題轉化為一維的問題。最後子矩陣一定是在某兩行之間的。假設我們認為子矩陣在第i行和第j列之間,我們如何得到i和j呢,對,列舉。 列舉所有1<=i<=j<=m,表示最終子矩陣選取的行範圍。
我們把每一列第i行到第j行之間的和求出來,形成乙個陣列c,於是乙個第i行到第j行之間的最大子矩陣和對應於這個和陣列c的最大子段和。於是,我們的演算法變為:
1
2
3
4
5
6
7
8
9
fori=
1tomdo
forj=i
tomdo //計
算第每列
第i行到
第j列的
和
fork=1
tondo c[
k]=(
j==i)?
a[i][
k] :
(c[k]+a
[j][
k])endfor
//求c的最大
子段和記
錄全域性最
優結果
endfor
endfor
我們看看標為紅色的部分 就是求每列第i行到第j行之間的所有數的和,我們沒有再用乙個迴圈求,而是隨著j的增長,每次把第j行的結果疊加到之前的和上。 另外求c的最大子陣列和是個線性時間演算法,實際上它可以和那個k的for迴圈合併在一起,不過不影響時間複雜度。時間複雜度是o(m^2n)。
最後,我們來提供輸入輸出資料,由你來寫一段程式,實現這個演算法,只有寫出了正確的程式,才能繼續後面的課程。
輸入
第1行:m和n,中間用空格隔開(2 <= m,n <= 500)。第2 - n + 1行:矩陣中的元素,每行m個數,中間用空格隔開。(-10^9 <= m[i] <= 10^9)
輸出
輸出和的最大值。如果所有數都是負數,就輸出0。
輸入示例
3 3-1 3 -1
2 -1 3
-3 1 2
輸出示例
7
這個題是51nod動態規劃入門教程裡的第一題。。。
**:#include#include#define inf 0x3f3f3f3f
using namespace std;
int flag;
int n,m;
long long maxx=-inf;
int del(long long c)
return max1;
}int main()
long long h;
flag=0;
for(int j=0;j0)
flag=1;
int l=del(c);
if(l>maxx)
maxx=l;}}
if(flag==0)
cout<<"0"<
最大子段和 最大子矩陣和
給出n個整數序列 可能為負數 組成的序列a1,a2,an,求該序列形如 的子段和的最大值。當所有整數均為負數時,定義最大子段和為0。多測試用例。每個測試用例佔2行 第一行是序列的個數n 0 n 10000 第二行是n個整數。為每個測試用例輸出一行結果 最大子段和。6 2 11 4 13 5 2 31...
最大子矩陣和
前言 今天花了很長時間,看了無數人寫的帖子,但是幾乎沒有人把這個問題一下子說得很清楚,所以,我把這個問題按照自己的思路寫出來,希望能夠把這個問題講清楚。問題 求乙個m n的矩陣的最大子矩陣和。比如在如下這個矩陣中 0 2 7 0 9 2 6 2 4 1 4 1 1 8 0 2 擁有最大和的子矩陣為 ...
最大子矩陣和
前言 今天花了很長時間,看了無數人寫的帖子,但是幾乎沒有人把這個問題一下子說得很清楚,所以,我把這個問題按照自己的思路寫出來,希望能夠把這個問題講清楚。問題 求乙個m n的矩陣的最大子矩陣和。比如在如下這個矩陣中 0 2 7 0 9 2 6 2 4 1 4 1 1 8 0 2 擁有最大和的子矩陣為 ...