UVA 108 Maximum Sum

UVA 108 Maximum Sum

题面翻译

给定一个含有正负数的二维数组,找出有最大和的子矩阵。矩阵的和指矩阵中所有元素的和。 一个子矩阵是任意在总矩阵中大小为1x1或更大的邻近子数组,例如在下面的矩阵中: 0 −2 −7 0

9 2 −6 2

−4 1 −4 1

−1 8 0 −2

(最大子矩阵)在左下方:

9 2

−4 1

−1 8

并且和为15.

输入:

包括一个N和NxN的矩阵 N<=100 矩阵中的数字在区间[-127,127]内

输出:

最大子矩阵的和

题目描述

PDF

UVA 108 Maximum Sum_第1张图片

输入格式

UVA 108 Maximum Sum_第2张图片

输出格式

样例 #1

样例输入 #1

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

样例输出 #1

15

solution

采用贪心算法,先计算从起点(0,0)位置到(i,j)位置为终点矩阵的和,并记为rec_sum[i][j],然后可以求得从起点(x1,y1)位置到(x2,y2)位置为终点矩阵的和,即rec_sum[x2][y2]-rec_sum[x1-1][y2]-rec_sum[x2][y1-1]+ rec_sum[x1-1][y1-1],然后可以遍历整个数字计算起点(x1,y1)位置到(x2,y2)位置为终点矩阵的和,并得到最大值

//
// Created by Gowi on 2023/11/29.
//

#include 

#define N 150

using namespace std;

int main() {
    int n;
    cin >> n;
    int arr[N][N] = {0};
    int rec_sum[N][N] = {0}; //sum[i][j]以(0,0)位置为起点,(i,j)位置为终点的矩阵内各元素的和
    int row_sum[N][N] = {0}; //row_sum[i][j] 从(i,0)到(i,j)的和
    int res = -999999999;
    for (int i = 1; i <= n; ++i) {
        for (int j = 1; j <= n; ++j) {
            cin >> arr[i][j];
            row_sum[i][j] = row_sum[i][j - 1] + arr[i][j];
        }
    }
    for (int i = 1; i <= n; ++i) {
        for (int j = 1; j <= n; ++j) {
            for (int k = 1; k <= i; ++k) {
                rec_sum[i][j] += row_sum[k][j];
            }
        }
    }
    for (int x1 = 1; x1 <= n; ++x1) {
        for (int y1 = 1; y1 <= n; ++y1) {
            for (int x2 = x1; x2 <= n; ++x2) {
                for (int y2 = y1; y2 <= n; ++y2) {
                    res = max(res,
                              rec_sum[x2][y2] - rec_sum[x1 - 1][y2] - rec_sum[x2][y1 - 1] +
                              rec_sum[x1 - 1][y1 - 1]);
                }
            }
        }
    }
    cout << res << endl;
}

你可能感兴趣的:(算法,算法,c++,数据结构)