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;
}
posted @ 2020-07-16 10:02  shuitiangong  阅读(141)  评论(0编辑  收藏  举报