1. 程式人生 > >最大子矩陣,最大連續子數組進階,動態規劃初級,poj1050

最大子矩陣,最大連續子數組進階,動態規劃初級,poj1050

ostream 子數組 images 使用 運行時間 規劃 out 思考 turn

題目描述:現給出一個N*N矩陣,要求求出擁有最大和的子矩陣的和。

例如:

技術分享

這樣的一個矩陣,最大子矩陣的和為15;

此題可以讓人聯想到求最大連續子數組,求最大子數組在上一篇文章中http://www.cnblogs.com/tz346125264/p/7560708.html。

分析:最大子矩陣可以看為求最大連續子數組拓展到二維數組上,因為矩陣的性質同樣在橫向豎向上需要連續,那麽可以想辦法將這個二維數組簡化為求連續子數組。

思考:

1.要求最大子矩陣,必須保證每個矩陣都被瀏覽到,為了保證運行時間盡可能不要重復瀏覽同一矩陣,故需制定規則,規則定為用i表示起始行,j表示終止行,j>=i,再使用k對列進行遍歷,即可覆蓋所有矩陣。

2.進行化簡成求連續子數組操作,以上為例,設i=2,j=4那麽這個矩陣是這樣技術分享,那麽化為連續子數組即為4(9-4-1),11(2+1+8),-10(-6-4+0),1(2+1-2)

求這個連續數組的最大連續子數組和便是這個矩陣(以i=2作為起始行,j=4作為終止行)的最大子矩陣,如此,整個矩陣的最大子矩陣便是這些最大子矩陣中的最大值。

上代碼:

#include<iostream>
#include<cstring>
using namespace std;

int main(){
    int n;
    int a[101][101];
    int temp[101
]; cin>>n; for(int i=1;i<=n;i++){ for(int j=1;j<=n;j++){ cin>>a[i][j]; /* 為什麽要進行相加? 在化簡為求連續最大子數組時,需要將i到j行的數進行相加sum(i,j),而這個sum{i,j}可有sum{0,j}-sum{0,i}得到 為此提前做出相加方便之後化簡 */ a[i][j]+=a[i-1
][j]; } } int max = -10000; for(int i=1;i<=n;i++){ for(int j=i+1;j<=n;j++){ memset(temp,0,sizeof(temp)); //求最大連續子數組操作 for(int k=1;k<=n;k++){ if(temp[k-1]>=0){ temp[k]=temp[k-1]+a[j][k]-a[i][k]; }else{ temp[k]=a[j][k]-a[i][k]; } if(temp[k]>max){ max = temp[k]; } } } } cout<<max<<endl; return 0; }

最大子矩陣,最大連續子數組進階,動態規劃初級,poj1050