編程之美讀書筆記2.15 - 子數組之和的最大值(二維)

來源:互聯網
上載者:User

標籤:編程之美

http://blog.csdn.net/pipisorry/article/details/39083073

問題:

求二維數組(矩陣)的子矩陣之和的最大值。

亦可見:http://poj.org/problem?id=1050



解法1:(解釋見注釋)

每個子矩陣由列長、行長和左上方的元素位置決定。如果我們指定左上方的元素位置 (i,j) 和列長 c,那麼可以求所有這些子矩陣中和最大的。然後,變化列長 c,可以求以 (i,j) 為左上方的最大和子矩陣。最所有左上方位置再求最大和子矩陣,問題就解決了。令 OPT(i,j,c) 表示以 (i,j) 為左上方,列長為 c 的最大和子矩陣之和,OPT(i,j) 表示以 (i,j) 為左上方的最優解,而 S(i,u,v) 表示第 i 行中從列 u 到列 v所有元素之和。則

    OPT(i,j,c) = OPT(i+1,j,c) + S(i,j,j+c-1)

    OPT(i,j) = max { OPT(i,j,c) : 1 <= c <= n }

其中,j+c-1 <= n。當 i >m 時, OPT(i,j,c) = 0。一共有 O(mn) 個 OPT(i,j) 子問題,而每個 OPT(i,j) 又可以有 n 個決策,因此,總的解規模有 O(mn2 ) 個 OPT(i,j,c)。每個這樣的子問題可以在 O(1) 時間內解決(想想怎麼做到),因此,時間複雜度為 O(mn2 )。


/*直接枚舉法O( N^2*M^2*O(sum()) )Time Limit Exceeded*/static int submatrixSum(int **a, int row, int row_end, int col, int col_end){int sum = 0;for(int i = row; i <= row_end; i++)for(int j = col; j <= col_end; j++)sum += a[i][j];return sum;}static int maxSubmatrixSum1(int **a, int n){int max_sum = INT_MIN;int sum;int max_row, max_row_end, max_col, max_col_end;for(int row = 0; row < n; row++){for(int col = 0; col < n; col++){//子矩陣左上方位置for(int row_end = row; row_end < n; row_end++)for(int col_end = col; col_end < n; col_end++){//4個屬性確定一個子矩陣sum = submatrixSum(a, row, row_end, col, col_end);//計算每個子矩陣的和if(sum > max_sum){max_sum = sum;/*max_row = row;max_row_end = row_end;max_col = col;max_col_end = col_end;*///printf("%d\n", max_sum);}}}}/*printf("\n            col\tcol_end\n            %d\t%d\n", max_col, max_col_end);//輸出子矩陣位置(4個屬性)printf("row     %d\nrow_end %d\n", max_row, max_row_end);*/return max_sum;}

解法2:

/*DP演算法 O(N^2*M)*/static int maxSubmatrixSum2(int **a, int n){int ***row_sum = (int ***)malloc(sizeof(int **) * n);for(int i = 0; i < n; i++)assert( row_sum[i] = (int **)malloc(sizeof(int *) * n) );for(int i = 0; i < n; i++)for(int j = 0; j < n; j++)assert( row_sum[i][j] = (int *)malloc(sizeof(int) * n) );//計算row_sum[i][j][c]為第i行j列到c列的和for(int i = 0; i < n; i++)//初始化row_sum[i][j][c]為0for(int j = 0; j < n; j++)memset(row_sum[i][j], 0, sizeof(int) * n);//!!!for(int i = n - 1; i >= 0; i--){for(int j = 0; j < n; j++){for(int c = j; c < n; c++)if(c == 0)row_sum[i][j][c] = a[i][c];elserow_sum[i][j][c] = row_sum[i][j][c - 1] + a[i][c];}}//將row_sum[i][j][c]轉換成第i行j列到c列的和的最優解for(int i = n - 2; i >= 0; i--){//row_sum[n-1][j][c]不變for(int j = 0; j < n; j++)for(int c = j; c < n; c++){if(row_sum[i+1][j][c] > 0)row_sum[i][j][c] += row_sum[i+1][j][c];}}//求以[i, j]為左上方的矩形最優解int **optij = (int **)malloc(sizeof(int *) * n);for(int i = 0; i < n; i++)optij[i] = (int *)malloc(sizeof(int) * n);for(int i = 0; i < n; i++)memset(optij[i], INT_MIN, sizeof(int) * n);for(int i = 0; i < n; i++){for(int j = 0; j < n; j++)for(int c = j; c < n; c++){if(row_sum[i][j][c] > optij[j][j])optij[j][j] = row_sum[i][j][c];}}//求整體最優解int max_sum = INT_MIN;for(int i = 0; i < n; i++){for(int j = 0; j < n; j++){if(optij[i][j] > max_sum)max_sum = optij[i][j];}}return max_sum;}

測試:

int main(){assert( freopen("BOP\\maxSubmatrixSum.in", "r", stdin) );//int cases;//測試案例數目//scanf("%d", &cases);//while(cases--){int n;//每個案例中matrix維度scanf("%d", &n);int **a = (int **)malloc(sizeof(int*) * n);for(int i = 0; i < n; i++)a[i] = (int *)malloc(sizeof(int) * n);for(int i = 0; i < n; i++)for(int j = 0; j < n; j++)scanf("%d", &a[i][j]);//printf("%d\n", maxSubmatrixSum1(a, n) );printf("%d\n", maxSubmatrixSum2(a, n) );//}fclose(stdin);return 0;}
測試案例:

3


2
1 1
1 1


4
0 -2 -7 0 
9 2 -6 2 
-4 1 -4 1 
-1 8 0 -2 


3
3 -1 4
3 -1 4
3 -1 4




output:
4
15
18

from:

http://blog.csdn.net/pipisorry/article/details/39083073

ref:

http://blog.csdn.net/pipisorry/article/details/39048485

編程之美 書p190


編程之美讀書筆記2.15 - 子數組之和的最大值(二維)

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.