看到很多人说二位前缀和,不禁有些奇怪,有那么复杂吗?这题完全就用不到动态规划呀,纯数字计算不就好了?

说说我的思路,首先维护两个一维数组row和col,分别保存矩阵每一行的元素和,与每一列的元素和。这一步在数据输入的时候就完成了,同时我们还得到了矩阵所有元素的和sum。

接下来分别计算横着切和竖着切,以横着切为例,初始时ans = sum,s1 = 0,s2 = sum。

遍历数组row,s1 += row[i],s2 -= row[i]。如果s1和s2差的绝对值 < ans,更新ans。当s2 < s1时跳出循环。

竖着切一样操作,只不过吧数组row换成col即可。最后输出ans。

下面贴出c++代码。

#include <iostream>
#include <vector>
using namespace std;

int main() {
    int n, m, a;
    cin >> n >> m;
    vector<int> row(n, 0), col(m, 0);
    long long sum = 0;
    for (int i = 0; i < n; ++i) {
        for (int j = 0; j < m; ++j) {
            cin >> a;
            row[i] += a;
            col[j] += a;
            sum += a;
        }
    }
    long long ans = sum;
    long long s12, s1 = 0, s2 = sum;
    for (int i = 0; i < n; ++i) {
        s1 += row[i];
        s2 -= row[i];
        s12 = abs(s2 - s1);
        ans = min(ans, s12);
        if (s2 < s1) break;
    }
    s1 = 0;
    s2 = sum;
    for (int i = 0; i < m; ++i) {
        s1 += col[i];
        s2 -= col[i];
        s12 = abs(s2 - s1);
        ans = min(ans, s12);
        if (s2 < s1) break;
    }
    cout << ans;
}