Maximum Sum

46 篇文章 1 订阅

1146. Maximum Sum

Time limit: 1.0 second
Memory limit: 64 MB
Given a 2-dimensional array of positive and negative integers, find the sub-rectangle with the largest sum. 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. A sub-rectangle is any contiguous sub-array of size 1 × 1 or greater located within the whole array.
As an example, the maximal sub-rectangle of the array:
0−2−70
9 2−62
−4 1−41
−1 80−2
is in the lower-left-hand corner and has the sum of 15.

Input

The input consists of an  N ×  N array of integers. The input begins with a single positive integer  Non a line by itself indicating the size of the square two dimensional array. This is followed by  N  2integers separated by white-space (newlines and spaces). These  N  2 integers make up the array in row-major order (i.e., all numbers on the first row, left-to-right, then all numbers on the second row, left-to-right, etc.).  N may be as large as 100. The numbers in the array will be in the range [−127, 127].

Output

The output is the sum of the maximal sub-rectangle.

Sample

input output
4
0 -2 -7 0
9 2 -6 2
-4 1 -4 1
-1 8 0 -2
15
/**最大子矩阵之和,方法如下:复杂度(O(N^4))**/
#include<iostream>
#include<cstdio>
#include<cstring>

using namespace std;
#define inf 0x7fffffff
#define maxn 110

int n,ans=0;
int Map[maxn][maxn];
int sum[maxn][maxn];
int sumh[maxn];


void read()//将每个数字输入,并按照行,压缩成数列
{
    scanf("%d",&n);
    for(int j=1; j<=n; j++)
        for(int k=1; k<=n; k++)
        {
            scanf("%d",&Map[j][k]);
            sum[j][k]=sum[j][k-1]+Map[j][k];
        }
}

int Get()//获取最大连续子序列的和
{
    int s=-inf;
    for(int j=1; j<=n; j++)//枚举起点
        for(int k=j; k<=n; k++)//枚举终点
        {
            if(sumh[k]-sumh[j-1]>s)
                s=sumh[k]-sumh[j-1];//就是这样
        }
    return s;
}

void DP()
{
    int max=-inf;
    for(int l=0; l<=n-1; l++)//枚举要压缩的列数
        for(int i=1; i<=n-l; i++)//枚举压缩的起点
        {
            memset(sumh,0,sizeof(sumh));
            for(int j=1; j<=n; j++)
                sumh[j]=(sum[j][i+l]-sum[j][i-1])+sumh[j-1];//将矩阵按行压缩后,成为数列,存于sumh中
            int temp=Get();//获取压缩后,最大连续子序列的和
            if(temp>max)
                max=temp;//取最大连续子序列和的最大值
        }
    ans=max;//就是答案
}

void print()
{
    printf("%d\n",ans);
}

int main()
{
    read();
    DP();
    print();
    return 0;
}



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值