題目大意:給定乙個n階方陣(1<=n<=100),其元素的取值範圍為[-127,127]。求其中的乙個m*p維子矩陣(1<=m<=100,1<=p<=100),要求使該子矩陣中元素的和最大。
求最大子矩陣,大一的時候乙個作業即是這個題目,忘了當時怎麼寫的了,重寫一遍。首先求一維陣列的最大子段,也是dp問題。
假設陣列arr[size],f[i] 是以「第i個位置為結束點的子段」的最大和。列舉所有位置,即列舉所有 i。注意到 f[i] 是包含 i 位置的最大和子段(假設不包含 i 位置,則在列舉到小於 i 位置(假設為 j 位置)時候已經算出包含 i 位置最大和子段),則有:
f[i] = max(f[i-1], 0)+arr[i]
意思是如果包含 i-1 點的最大和子段小於0,則對包含 i 點的最大和子段沒有貢獻,f[i] = arr[i]。反之,如果包含 i-1 點的最大和子段大於0,則對包含 i 點的最大和子段有正貢獻,則需要加上:f[i] = f[i-1] + arr[i]
int sumsubarray(constint arr, const
int size)
這就是用dp解決一位陣列的最大和子段。參考
解決二維陣列的最大子矩陣,轉化為一維的即可。列舉從 i (i從0取到max_row)行到 j (j從i取到max_row)行,temp[size]中的每個元素為第 i 行到第 j 行的每一列的和,對temp求最大子段即是對二維陣列求最大子矩陣。我的**如下:
#include
2:using
namespace std;
3:const
int min_int = -(1<<15);
4:
5:int sumsubarray(const
int arr, const
int size)
6:
15:return sum;
16: }
17:
18:int sumsubarray2(int** arr, const
int row, const
int col)
19:
34:int sumtemp = sumsubarray(temp, col);
35:if (sum36: sum = sumtemp;
37: }
38: }
39:delete temp;
40:return sum;
41: }
42:
43:int main()
44:
59:
60:int sum = sumsubarray2(arr, arrsize, arrsize);
61: cout << sum << endl;
62:
63:delete arr[0];
64:delete arr;
65:return 0;
66: }參考
POJ 1050 To the Max(最大矩陣)
和序列中無長度限制的最大子段和相同,如果當前的sum 0,那麼它還有一定的價值,所以繼續往上累加 如果當前sum 0,即sum不僅沒有價值,反而會使後面的和更小,所以將sum重置為0為最優。矩陣中維護每一列上的字首和,列舉所選矩陣上限i,下限j,列舉列數k,重複上述過程,記錄整個過程中的最大值即為答...
POJ結題報告 1050 To the Max
題目描述 思路 這道題最基本和原始的方法是窮舉,但是窮舉是乙個o n 4 的演算法,題目中明確說明測試資料最大可能是100 100,窮舉會超出題目時間限制1000ms。而動態規劃是這道題解決的方法。首先子矩陣的和可以轉化為子矩陣中每一列先求和再將他們加起來,即 9 2 4 1 1 8 的和可以表示為...
poj 1050 動態規劃
題目 求最長序列的和的拓展,有一維拓展到二維,首先判斷每一行的最大值,然後記錄下最大的值,再將然後,把第i行後的各行對應列的元素加到第i行的對應列元素,每加一行,就求一次最大欄位和,這樣就把子矩陣的多行壓縮為一行了,一行了就是最大欄位和了啊!include include using namespa...