随手练——ZOJ-1074 To the Max(最大矩阵和)

时间:2023-09-12 21:56:20

To the Max

http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=1074

动态规划(O(n^3))

获得一维数组的最大子数组和:(O(n))

int MaxSubSum(int* arr, int n) {
     << , t = ;
    ; i < n; i++) {
        t += arr[i];
        if (t > max) max = t;
        ) {
            t = ;
        }
    }
    return max;
}

目标:

通过一维数组的最大子数组和,找到二维数组的最大矩阵和

1、形如这样的一个二维数组,将其 “压扁” 成为一维数组(数组每列元素的和):

随手练——ZOJ-1074 To the Max(最大矩阵和)

2、首先特殊情况,假设最大子矩阵是二维数组中的粉色部分,则相对应一维数组的最大子数组和就一定也是粉色部分。

随手练——ZOJ-1074 To the Max(最大矩阵和)

3、推广到所有情况,假设最大子矩阵和是二维数组中的,p~q行,i~j列 ;则相对应的 p~q行 的列元素和的最大子数组和就是是 i 到 j 。

代码:

#include <iostream>
#include <string.h>
#include <stdio.h>    

using namespace std;
int n, res = 0x80000000;
][];

int MaxSubSum(int *arr) {
     << , t = ;
    ; i < n; i++) {
        t += arr[i];
        if (t > max) max = t;
        ) {
            t = ;
        }
    }
    return max;
}

int main()
{
    cin >> n;
    ; i < n; i++) {
        ; j < n; j++) {
            scanf("%d", &arr[i][j]);
        }
    }
    int* arrSum = new int[n];
    ; i < n; i++) {
        memset(arrSum, , sizeof(int) * n);
        for (int j = i; j < n; j++) {
            ; k < n; k++) {
                arrSum[k] += arr[j][k];
            }
            int t = MaxSubSum(arrSum);
            res = t > res ? t : res;
        }
    }
    cout << res << endl;
    ;
}