AcWing 126 最大的和(贪心,前缀和,暴力ver.)
解题思路
这题最简单的暴力就是枚举左上角和右下角,但是其实有个稍微好一点点的方法。我们可以枚举矩形一条边的边长,至于另一条边的边长,我们会发现,在不断往下延伸的过程中,增加了很多子矩阵,如果已经延伸的部分都是负数,那么可以全部舍去,从一个和为正数的子矩阵开始延伸。这样的话时间复杂度就降到了\(O(n^3)\)。
代码
const int maxn = 1e2+10;
int g[maxn][maxn], ans = -114514;
int main() {
int n; scanf("%d",&n);
for (int i = 1; i<=n; ++i)
for (int j = 1; j<=n; ++j)
scanf("%d",&g[i][j]);
for (int i = 1; i<=n; ++i)
for (int j = 1; j<=n; ++j)
g[i][j] += g[i][j-1];
for (int i = 1; i<=n; ++i)
for (int j = i; j<=n; ++j) {
int sum = 0;
for (int k = 1; k<=n; ++k) {
sum += g[k][j]-g[k][i-1];
ans = max(ans,sum);
if (sum<0) sum = 0;
}
}
printf("%d\n",ans);
return 0;
}