分析我們已經解決了一維的問題(基礎篇中的最大子段和問題),現在變成二維了,我們看看能不能把這個問題轉化為一維的問題。最後子矩陣一定是在某兩行之間的。假設我們認為子矩陣在第i行和第j列之間,我們如何得到i和j呢,對,列舉。 列舉所有1<=i<=j<=m,表示最終子矩陣選取的行範圍。
我們把每一列第i行到第j行之間的和求出來,形成乙個陣列c,於是乙個第i行到第j行之間的最大子矩陣和對應於這個和陣列c的最大子段和。於是,我們的演算法變為:
for i = 1 to m do我們看看標為紅色的部分 就是求每列第i行到第j行之間的所有數的和,我們沒有再用乙個迴圈求,而是隨著j的增長,每次把第j行的結果疊加到之前的和上。 另外求c的最大子陣列和是個線性時間演算法,實際上它可以和那個k的for迴圈合併在一起,不過不影響時間複雜度。時間複雜度是o(m^2n)。for j = i to m do
//計算第每列第i行到第j列的和
for k = 1 to n do
c[k] = (j == i)?a[i][k] : (c[k] + a[j][k])
endfor
//求c的最大子段和 記錄全域性最優結果
endfor
endfor
最後,我們來提供輸入輸出資料,由你來寫一段程式,實現這個演算法,只有寫出了正確的程式,才能繼續後面的課程。
輸入
第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
1超時!python的執行效率阿!!#最大子矩陣
2def
array(n):
3 a=
4for i in
range(n):56
return
a
7def
array2(m,n):
8 a=
9for i in
range(m):
10 b=array(n)
1112
return
a
13 line=input().split()
14 m=int(line[0])
15 n=int(line[1])
16 a=array2(n,m)
17 c=array(m)
18for i in
range(n):
19 line=input().split()
20for j in
range(m):
21 a[i][j]=int(line[j])
22 ans=-10000000000
23for i in
range(n):
24for j in
range(i,n):
25for k in
range(m):
26 c[k]=a[j][k] if i==j else c[k]+a[j][k]
27 last=-10000000000
28for k in
range(m):
29 last=max(last,0)+c[k]
30 ans=max(ans,last)
31print(ans)
1 #include2int max(int a,intb)6
intmain()
15 ans=-1000000000
;
16for(int i=0;i)
17for (int j=i;j)
18
30}
31 printf("
%ld"
,ans);
32 }
最大子矩陣(動態規劃)
最大矩陣和顧名思義,就是乙個矩陣和最大,例如下面的矩陣 0 2 7 0 9 2 6 2 41 41 1 80 2 最終找到了和為15的矩陣 9 2 41 18所選的矩陣沒有規定,只要在這個大矩陣中,就可以了,那麼我們需要限定它的行和列 我們用三個for迴圈把所有的行的情況列舉,分別是i,j,k i從...
動態規劃 最大子矩陣的和
問題 最大子矩陣的和 最大子矩陣的和這個問題實際上是子串的最大和向二維空間的擴充套件!我們如果把每一列都看作乙個數的話,實際上也是個子串的最大和問題!不多說啦,大家看 體會吧!package com.liheng.algorithm author administrator 利用動態規劃求最大子矩陣...
動態規劃 最大子矩陣和 收藏
最大子矩陣問題 問題描述 具體見 給定乙個n n 0讓我們先來看另外的乙個問題 最大子段和問題 給定乙個長度為n的一維陣列a,請找出此陣列的乙個子陣列,使得此子陣列的和sum a i a i 1 a j 最大,其中i 0,i i,jsum maxsofar sum 第二種方法 帶記憶的遞推法 cum...