POJ1050 最大子矩阵

To the Max

http://poj.org/problem?id=1050

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

解题思路
本题是典型的动态规划,实际是求矩阵的最大子矩阵(和最大)。这是将序列的连续最大段和问题扩展到二维的一题。

序列的最大连续段和问题思路:
原序列a    0 -2 -7 0 9 2 -6 2
记录    b    0  0  0 0 9 11 5 7
结果为11

将这个问题扩展到二维,则先将选中的几行,逐列相加变为一个一维数组。(如果是一行的情况,则直接使用序列的最大连续段和方法)

多行变为一行时:例如
 0 -2 -7  0
 9  2 -6  2
-4  1 -4  1
-1  8  0 -2

当i=0, j=2时,则选择0,1,2行
    0 -2 -7   0
    9  2 -6   2
   -4  1 -4   1
a: 5  1 -17 3
b: 5  6  0   3
答案为3

参考
http://blog.csdn.net/jqandjq/article/details/5060283

#include <stdio.h>
#include <stdlib.h>

int main (int argc, char const* argv[])
{
    int i, j, k, l, n, ans, sum, max;
    int a[100][100];
    int b[100];

    scanf("%d", &n);
    for (i = 0; i < n; i++) {
        for (j = 0; j < n; j++) {
            scanf("%d", &a[i][j]);
        }
    }

    ans = 0;
    for (i = 0; i < n; i++) {
        for (j = 0; j < n; j++) {
            if (i == j) {
                for (k = 0; k < n; k++) {
                    b[k] = a[i][k];
                }
            } else {
                for (k = 0; k < n; k++) {
                    b[k] = 0;
                    for (l = i; l <= j; l++) {
                        b[k] += a[l][k];
                    }
                }
            }

            sum = 0;
            max = 0;
            for (k = 0; k < n; k++) {
                sum += b[k];
                if (sum > max) {
                    max = sum;
                }
                if (sum < 0) {
                    sum = 0;
                }
            }

            if (max > ans) {
                ans = max;
            }
        }
    }

    printf("%d\n", ans);

    return 0;
}

 

你可能感兴趣的:(dp,poj)