码迷,mamicode.com
首页 > 编程语言 > 详细

连续子数组(二维)的最大和

时间:2015-05-12 15:18:07      阅读:147      评论:0      收藏:0      [点我收藏+]

标签:

题目连接如下:

http://www.acmerblog.com/max-sum-rectangle-in-a-matrix-5955.html

一维数组的连续子数组的最大和

题目:输入一个整型数组,数组里有正数也有负数。数组中一个或连续的多个整数组成一个子数组。求所有子数组的和的最大值。要求时间负责度为O(n)。

假如输入数组为{1,-2,3,10,-4,7,2,-5},我们尝试从头到尾累加其中的正数,初始化和为0,第一步加上1,此时和为1,第二步加上-2,此时和为-1,第三步加上3,此时我们发现-1+3=2,最大和2反而比3一个单独的整数小,这是因为3加上了一个负数,发现这个规律以后我们就重新作出累加条件:如果当前和为负数,那么就放弃前面的累加和,从数组中的下一个数再开始计数。

剑指offer和编程之美都有此题。参考这里:剑指offer(14)-最大子向量和 九度1372。算法可以优化为下面的几行代码:

二维数组的连续子数组的最大和

二维数组的连续子数组即为一个矩阵,如下图所示

技术分享

设矩阵的坐上顶点为A(i,j), 右下顶点为 B(endi, endj). 在图中即为 A(1,1), B(3,3)。我们可以用Rect(A,B)即 (1,1,3,3,)来表示矩形区域。

 

代码:

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

int a[100][100];
int n,m;
int p[100][100];

int main()
{
    freopen("in.txt","r",stdin);
    int i,j;
    int max , imax , jmax , istart , jend;
    while( ~scanf("%d%d",&n,&m) )
    {
        memset(a , 0 , sizeof(a) );
        for( i = 0 ; i < n ; i++ )
        {
            for( j = 0 ; j < m ; j++ )
            {
                scanf("%d",&a[i][j]);
                p[i][j] = a[i][j];
                if( j -1 >= 0 )
                    p[i][j] += p[i][j-1];
                if( i -1 >= 0 )
                    p[i][j] += p[i-1][j];
                if( i-1 >=0 && j-1 >= 0 )
                    p[i][j] -= p[i-1][j-1];
            }
        }
        for( i = 0 ; i < n ; i++ )
        {
            for( j = 0 ; j < m ; j++ )
                printf("%3d  ", p[i][j] );
            printf("\n");
        }
        max = a[0][0];
        int temp , tempstart , tempend;
        int z;
        for( i = 0 ; i < n; i++ )
        {
            for( j = i ; j < n ; j++ )
            {
                temp = p[j][0];
                if( i - 1 >= 0 )
                    temp -= p[i-1][0];
                tempstart = tempend = 0;
                for( z = 1; z < m ; z++)
                {
                    int zz = p[j][z];
                    if( z -1 >= 0 )
                        zz -= p[j][z-1];
                    if( i - 1 >= 0 )
                        zz -= p[i-1][z];
                    if( i-1>= 0 && z-1 >= 0 )
                        zz += p[i-1][z-1];
                    if( (temp + zz) > zz )
                    {
                        temp = temp + zz;
                        tempend = z;       
                    }
                    else
                    {
                        temp = zz;
                        tempstart = tempend = z;
                    }
                    if( temp > max )
                    {
                        max = temp;
                        imax = i; jmax = j;
                        istart = tempstart; jend = tempend;
                    }
                }
            }
        }
        printf("(%d,%d) - (%d,%d) sum is %d \n" , imax , istart , jmax , jend , max );
    }
    return 0;
}

 

连续子数组(二维)的最大和

标签:

原文地址:http://www.cnblogs.com/zhping/p/4497156.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!