HDU 1081 最大矩形和

来源:互联网 发布:网络打鱼赌钱游戏破解 编辑:程序博客网 时间:2024/05/06 04:09

To The Max
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)
Total Submission(s): 9698 Accepted Submission(s): 4671

Problem Description
Given a two-dimensional array of positive and negative integers, a sub-rectangle is any contiguous sub-array of size 1 x 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 x 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

此题的关键是如何组织数据形式,不能单纯的对每一个读入的数据进行处理。考虑到最后结果也是和,用动规肯定是先行后列或者先列后行。所以dp[i][j]存的的第i行直到第j个数的和,然后dp[k][j] - dp[k][i-1]就是第行第j个数到i-1的和,接着k从1到N遍历类似一维求最大连续子列和。就求出了i-1到j这个宽度之间的最大矩阵。跟着外围的i,j遍历整个数组,找出最大的Max就是结果。

#include <iostream>#include <algorithm>#include <cstdio>#include <cstring>//#define LOCALusing namespace std;int dp[105][105];int main(){#ifdef LOCAL    freopen("data.in","r",stdin);    freopen("data.out","w",stdout);#endif // LOCAL    int N;    while(scanf("%d",&N)!=EOF){        int i,j,k;        memset(dp,0,sizeof(dp));        for(i = 1;i<=N;i++)            for(j = 1;j<=N;j++){                int term;                scanf("%d",&term);                dp[i][j] = dp[i][j-1] + term;            }        int Max = -0x3f3f3f3f;        for(i = 1;i<=N;i++){            for(j = i;j<=N;j++){                int sum = 0;                for(k = 1;k<=N;k++){                    if(sum<0)                        sum = 0;                    sum += dp[k][j] - dp[k][i-1];                    if(Max<sum)                        Max = sum;                }            }        }        printf("%d\n",Max);    }    return 0;}
0 0