POJ1050 To the Max (最大子段和,最大子矩阵)

来源:互联网 发布:怎么加入淘宝上门安装 编辑:程序博客网 时间:2024/05/21 16:55
题目地址:
http://poj.org/problem?id=1050
描述:
Given a two-dimensional array of positive and negative integers, a sub-rectangle is any contiguous sub-array of size 1*1 or greater located within the whole array. The sum of a rectangle is the sum of all the elements in that rectangle. In this problem the sub-rectangle with the largest sum is referred to as the maximal sub-rectangle. 
As an example, the maximal sub-rectangle of the array: 
0 -2 -7 0 
9 2 -6 2 
-4 1 -4 1 
-1 8 0 -2 
is in the lower left corner: 
9 2 
-4 1 
-1 8 
and has a sum of 15. 

分析

http://www.cnblogs.com/fll/archive/2008/05/17/1201543.html

假设最大子矩阵的结果为从第r行到k行、从第i列到j列的子矩阵,如下所示(ari表示a[r][i],假设数组下标从1开始):
  | a11 …… a1i ……a1j ……a1n |
  | a21 …… a2i ……a2j ……a2n |
  |  .     .     .    .    .     .    .   |
  |  .     .     .    .    .     .    .   |
  | ar1 …… ari ……arj ……arn |
  |  .     .     .    .    .     .    .   |
  |  .     .     .    .    .     .    .   |
  | ak1 …… aki ……akj ……akn |
  |  .     .     .    .    .     .    .   |
  | an1 …… ani ……anj ……ann |
那么我们将从第r行到第k行的每一行中相同列的加起来,可以得到一个一维数组如下:
(ar1+……+ak1, ar2+……+ak2, ……,arn+……+akn)
由此我们可以看出最后所求的就是此一维数组的最大子断和问题


将最大子矩阵问题分解为最大子段和。时间复杂度O(n^3)。

代码

#include <iostream>using namespace std;#include <string.h> //memset#define INF 0x3f3f3f3fconst int SZ=102;int d[SZ][SZ];int s[SZ];//最大子段和int MaxArray(int a[],int n){int m=-INF;int tmp=-1;for(int i=0;i<n;i++){if(tmp>0)tmp+=a[i];elsetmp=a[i];if(tmp>m)m=tmp;}return m;}int main(){int i,j,k,n;cin>>n;for(i=0;i<n;i++)for(j=0;j<n;j++)cin>>d[i][j];int ans=-INF,tmp;for(i=0;i<n;i++){memset(s,0,sizeof(int)*n);for(j=i;j<n;j++){for(k=0;k<n;k++)s[k]+=d[j][k];tmp=MaxArray(s,n);if(tmp>ans)ans=tmp;}}cout<<ans<<endl;return 0;}



0 0
原创粉丝点击