1 条题解

  • 0
    @ 2025-7-2 15:02:35

    思路

    最朴素的想法是枚举左上角和右下角,要用 44for 循环,加上二维前缀和,复杂度 O(n4)O(n^4)

    我们进行优化:

    枚举边界,如下图所示:边界 11、边界 22 和边界 33 就是枚举的边界。

    把边界 11 和边界 22 之间的每一列看做一个整体(图中的相同颜色),每个整体的值就是这些元素的累加和,我们枚举边界 33,找出一边界 33 作为右边界的最优矩形。

    找矩形的方法:

    假设有数组 aa,我们用 fif_i 表示已 ii 为终点的最大连续和。

    • 如果 fi1>0f_{i - 1} > 0fi=ai+fi1f_i = a_i + f_{i - 1}
    • 如果 fi10f_{i - 1} \leq 0fi=aif_i = a_i

    我们可以用前缀和求出整体的累加和,然后再用上面求 ff 数组的方法求出最优矩形。

    代码

    #include<bits/stdc++.h>
    using namespace std;
    
    const int N = 110;
    
    long long a[N][N];
    
    int main()
    {
        long long n, ans = -0x3f3f3f3f;
        cin >> n;
        for (int i = 1; i <= n; i ++ )
            for (int j = 1; j <= n; j ++ )
                cin >> a[i][j];
        for (int i = 1; i <= n; i ++ )
            for (int j = 1; j <= n; j ++ )
                a[i][j] += a[i - 1][j];
        for (int i = 1; i <= n; i ++ )
            for (int j = i; j <= n; j ++ )
            {
                long long sum = 0;
                for (int k = 1; k <= n; k ++ )
                {
                    sum = max(sum, 0ll) + a[j][k] - a[i - 1][k];
                    ans = max(ans, sum);
                }
            }
        cout << ans << endl;
        return 0;
    }
    
    • 1

    信息

    ID
    61
    时间
    1000ms
    内存
    256MiB
    难度
    7
    标签
    递交数
    19
    已通过
    8
    上传者