看到很多人说二位前缀和,不禁有些奇怪,有那么复杂吗?这题完全就用不到动态规划呀,纯数字计算不就好了?
说说我的思路,首先维护两个一维数组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;
}



京公网安备 11010502036488号