poj 1050 To the Max

ACM比赛整理

共 2225字,需浏览 5分钟

 ·

2021-12-13 00:37

To the Max


Description

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.

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 whitespace (spaces and newlines). These are the N^2 integers of the array, presented in row-major order. That is, all numbers in the first row, left to right, then all numbers in 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

Output the sum of the maximal sub-rectangle.

Sample Input

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

8 0 -2

Sample Output

15



到最大


描述

给定一个由正整数和负整数组成的二维数组,子矩形是位于整个数组中的任何大小为 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。数组中的数字将在 [-127,127] 范围内.

输出

输出最大子矩形的总和。

样本输入

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

-4 1 -4 1 -1


8 0 -2

样本输出

15



解题思路:

首先求矩形区域和显然是使用前缀和。然后要求出最大区域和,则应想到动态规划。
先使用dp[r,c,w,h]表示以(r,c)为矩形右下角顶点时形状为(w,h)的矩形区域和,但这样时间空间复杂度过高,必须简化。
现在使用dp[c,w],更新顺序为r从1到n,c从1到n,w从1到c(或从c到1),dp[c,w]表示当前行r下,以(r,c)为矩形右下角顶点时,矩形占用w列时,区域和的最大值。这样时间复杂度为O(N3),空间复杂度为O(N2),是可行的。
更新法则为

int dp_row=sum[r][c]-sum[r][c-l]-sum[r-1][c]+sum[r-1][c-l];
dp[c][l]=max(dp_row,dp[c][l]+dp_row);

代码:

#include 
#include
#define N 102
using namespace std;

int main()
{
int n;
int sum[N][N]={0};
//dp[C][L]
//以当前行C列处为矩形右下角顶点,占用L列时,矩形区最大和
int dp[N][N]={0};
cin>>n;
//矩形区域和-->二维前缀和
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++)
cin>>sum[i][j];
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++)
sum[i][j]+=sum[i-1][j]+sum[i][j-1]-sum[i-1][j-1];
//初始化
int max_val=-n*n*128;
for(int c=1;c<=n;c++)
for(int l=1;l<=c;l++)
dp[c][l]=sum[1][c]-sum[1][c-l];
//第一行已经初始化了,从第二行开始
//从上到下,从左到右,从1到c遍历l,扫描
for(int r=2;r<=n;r++)
for(int c=1;c<=n;c++)
for(int l=1;l<=c;l++)
{
int dp_row=sum[r][c]-sum[r][c-l]-sum[r-1][c]+sum[r-1][c-l];
dp[c][l]=max(dp_row,dp[c][l]+dp_row);
max_val=max(max_val,dp[c][l]);
}
cout<}



浏览 19
点赞
评论
收藏
分享

手机扫一扫分享

分享
举报
评论
图片
表情
推荐
点赞
评论
收藏
分享

手机扫一扫分享

分享
举报