給乙個二維陣列,求子陣列的和的最大值,也就是求子矩陣的最大和。
這道題的解題思路與2.14求陣列的子陣列之和的最大值有類似之處,具體步驟如下:
設原陣列為a,行數為row,列數為column.
1. 先求矩陣p(row+1,column+1), p[i,j]表示在a中以a[i-1,j-1]到a[0,0]為對角線的子矩陣的元素之和。
初始化:p[0,i]=0,i=0,1,...colum; p[i,0]=0,i=0,1,...row;
迭代求p[i][j]=p[i - 1][j] + p[i][j - 1] - p[i - 1][j - 1] + a[i-1][j-1]; //注意,因為res比v多了一行一列,因此res中的第[i,j]元素對應於v中第[i-1,j-1]的元素。
2. 將問題從二維轉化為一維,假設已將確定了子矩陣的上下邊界,分別為第r_min, r_max行,現在想要確定左右邊界。在r_min, r_max的區域裡,把每一列的元素看成乙個整體,bc[i]即表示在此區域的第i列的和,bc[i]=a[r_min,i]+a[r_min+1,i]+...+a[r_max,i];因此問題為先求bc陣列的每乙個元素(i=0,1,...,column),計算公式為bc[i]=p[r_max][i] - p[r_min - 1][i] - p[r_max][i- 1] + p[r_min - 1][i- 1](注意這裡也有1中出現的p的行列數比a大1,程式設計時需要轉換一下的小問題具體可參考程式) ;然後轉換為題2.14求陣列bc的子陣列之和的最大值。
3. 令r_min從0-(row-1), r_max從r_min-(row-1), 迭代所有可能的上下區域,並利用步驟2求該區域的最大子陣列之和,如果發現更大的和則更新最大值。
#include using namespace std;
vector> calculatesum(const vector> &v, int row, int column)
int ithcolmaxsum(const vector>&p,int r_min, int r_max, int icolumn)
int maxsum(vector>v)
if (allnum > maxsum)
maxsum = allnum;
} }return maxsum;
}int main(void)
, , , };
int res=maxsum(v);
return 0;
}
注意:用vector定義二維陣列v(n*m),這裡n為行數,m為列數,則可通過如下方法:
vector> v(n); //行數n一定不能少,它表示v有n個元素
for(int i=0;iv[i].resize(m);
程式設計之美 2 15 子陣列之和的最大值(二維)
思路,有了一維的思路,我們想辦法把二維問題轉化為一維的問題。我們假定已經選中了行的範圍是 a c 那麼把每一列中 a c的元素加起來就變成了乙個一維的問題。只需對行的範圍遍歷,再用一維的方法來解就可以了。注意,也可以對列的範圍遍歷,行和列那個小就對哪個遍歷。複雜度為o m n min m,n inc...
程式設計之美 求陣列的子陣列之和的最大值
前段子時間舍友恒恒問了我乙個問題 怎樣在乙個陣列中找到乙個子陣列使得各個元素之和最大,當時自己想了片刻,設定乙個變數sum,就說從左邊開始變數整個陣列,乙個個相加到sum中,發現了sum 0的話,就把sum設定為0就可以了,後來想了下,得到的結果未能保證正確,我們應該在遍歷的過程中儲存下sum的最大...
求陣列的子陣列之和的最大值(程式設計之美)
題目要求 乙個有n個整數元素的一維陣列 a 0 a 1 a n 2 a n 1 這個陣列當然有很多子陣列,那麼子陣列中和最大值是多少呢?1 子陣列是連續的 2 求子陣列的和,不用求子陣列的具體位置 3 陣列的元素時整數,所以陣列可能包含有正整數 零 負整數 解法一 暴力解法,從陣列的第0位開始遍歷陣...