POJ 1050 to max

给麦克斯
时限:1000 MS   内存限制:10000 K
提交材料共计:51175   接受:27064

描述

给定一个二维的正和负整数数组,子矩形是任意大小1*1或更大的相邻子数组,位于整个数组中。矩形的总和是该矩形中所有元素的总和。在这个问题中,带最大总和的子矩形称为最大子矩形。
作为例子,数组的最大子矩形:

0-2-7 0
9 2-6 2
-4 1-4 1
-1 8 0-2
位于左下角:

9 2
-4 1
-1 8
并且有15张。

输入

输入由n*n数组组成。输入首先由一行上的一个正整数n开始,指示平方二维数组的大小。接下来是n^2整数,由空格分隔(空格和空格)。这些是数组的n^2整数,以行主顺序呈现。也就是说,第一行中的所有数字,左到右,然后所有的数字在第二行,左到右等。n可能高达100。数组中的数字将在[-127127]范围内。

输出量

输出最大子矩形的总和。

样本输入

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

8  0 -2

样品输出

15

来源


考查:动态规划 最大子段和

提交情况:一次AC

收获:又认识了下最大连续子段和

在一维情况下最大连续子段和的求法是从左到有顺序扫描数据,以0为边界,当累加和小于0时则重置为0.动态规划的状态转移方程为

s=max{si-1+ai,ai},该方程和前面的描述是等价的。本题是对一维最大子段和的扩展,思路是从上到下找出所有的连续行(如第i行到第j行),然后计算每列从第i行到第j行的和,之后对这n个列的和进行一维最大子段和的计算,并找出最大的值。

AC_CODE:

[cpp]  view plain  copy
  1. #include <stdio.h>  
  2. #define MAX 101  
  3. int main()  
  4. {  
  5.     int n;  
  6.     int a[MAX][MAX]={0};  
  7.     int colsum[MAX][MAX]={0};  
  8.     int max=0,sum;  
  9.     scanf("%d",&n);  
  10.     for(int i=0;i<n;i++)  
  11.         for(int j=1;j<=n;j++)  
  12.         {  
  13.             scanf("%d",&a[i][j-1]);  
  14.             colsum[i][j]=colsum[i][j-1]+a[i][j-1];  
  15.         }  
  16.     for(int i=0;i<n;i++)  
  17.         for(int j=i;j<=n;j++)//从第i行到第j行  
  18.         {  
  19.             sum=0;  
  20.             for(int k=0;k<n;k++)//每列的和  
  21.             {  
  22.                 sum+=colsum[k][j]-colsum[k][i];  
  23.                 if(sum<0) sum=0;  
  24.                 else if(sum>max) max=sum;  
  25.             }  
  26.         }  
  27.     printf("%d/n",max);  
  28.     return 0;  
  29. }  
 

猜你喜欢

转载自blog.csdn.net/usernamezzz/article/details/79903481