D - 石之锤 URAL - 1146 (最大子矩阵和)

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 −7 0
9 2 −6 2
−4 1 −4 1
−1 8 0 −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 N on a line by itself indicating the size of the square two dimensional array. This is followed by N 2 integers 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.
Example
input output
4
0 -2 -7 0
9 2 -6 2
-4 1 -4 1
-1 8 0 -2
15

求最大子矩阵和的问题,就要类比求最大子序列的问题。
首先,在输入的时候处理数据,保证输入的dp[ i ][ j ] 代表的是第j列的前i行数字之和。
然后枚举行数,i, j, 计算出第i行和第j行之间的每一列的和的最大子序列,就是这个矩阵的矩阵和,最后,求出最大的就是整个矩阵的最大子矩阵和。

#include <bits/stdc++.h>
using namespace std;
#define INF 0x3f3f3f3f
int dp[123][123];
int main()
{
    int n;
    cin>>n;
    memset(dp, 0, sizeof(dp));
    for(int i=1; i<=n; i++)
    {
        for(int j=1; j<=n; j++)
        {
            int a;
            cin>>a;
            dp[i][j] = dp[i-1][j] + a;
        }
    }
    int maxn = -INF;
    for(int i=1;i<=n;i++)
    {
        for(int j=i;j<=n;j++)
        {
            int ans = 0;
            for(int k=1;k<=n;k++)
            {
                int t = dp[j][k] - dp[i-1][k];
                ans += t;
                if(ans>maxn)
                    maxn = ans;
                if(ans<0)
                    ans = 0;
            }
        }
    }
    cout<<maxn<<endl;
    return 0;
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值