Maximum Exploitation - ieeextreme15

这题其实并不难,比赛的时候自己脑子就是转不动==
Maximum Exploitation - ieeextreme15
题目大意:
有一个RxC的矩阵,用最多两个rxc的矩形去框这个矩阵,使覆盖的数字之和最大,输出最大值
1<=R,C<=1000

解题思路:
预处理以(i,j)为右下角顶点,(0,0)为左上角顶点范围内的 形状为rxc矩形所能覆盖的最大值p[i][j]
预处理以(i,j)为左上角顶点,(R,C)为右下角顶点范围内的 形状为rxc矩形所能覆盖的最大值q[i][j]
遍历就完事了

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N = 1e3 + 3;
int mz[N][N];
ll q1[N][N], q2[N][N], p1[N][N], p2[N][N], sum[N][N];
ll getsum(int a, int b, int c, int d)
{
    return sum[c][d] - sum[c][b - 1] - sum[a - 1][d] + sum[a - 1][b - 1];
}
int main()
{
    int n, m;
    int a, b;
    scanf("%d%d", &n, &m);
    scanf("%d%d", &a, &b);
    for (int i = 1; i <= n; i++)
    {
        for (int j = 1; j <= m; j++)
        {
            scanf("%d", &mz[i][j]);
            sum[i][j] = -sum[i - 1][j - 1] + sum[i - 1][j] + sum[i][j - 1] + mz[i][j];//矩形((0,0),(i,j))的元素和
        }
    }

    for (int i = a; i <= n; i++)
    {
        for (int j = b; j <= m; j++)
        {
            p1[i][j] = max(p1[i][j - 1], p1[i - 1][j]);
            p1[i][j] = max(p1[i][j], getsum(i - a + 1, j - b + 1, i, j));
        }
    }
    for (int i = b; i <= n; i++)
    {
        for (int j = a; j <= m; j++)
        {
            p2[i][j] = max(p2[i][j - 1], p2[i - 1][j]);
            p2[i][j] = max(p2[i][j], getsum(i - b + 1, j - a + 1, i, j));
        }
    }
    //
    for (int i = n - a + 1; i >= 0; i--)
    {
        for (int j = m - b + 1; j >= 0; j--)
        {
            q1[i][j] = max(q1[i][j + 1], q1[i + 1][j]);
            q1[i][j] = max(q1[i][j], getsum(i, j, i + a - 1, j + b - 1));
        }
    }
    for (int i = n - b + 1; i >= 0; i--)
    {
        for (int j = m - a + 1; j >= 0; j--)
        {
            q2[i][j] = max(q2[i][j + 1], q2[i + 1][j]);
            q2[i][j] = max(q2[i][j], getsum(i, j, i + b - 1, j + a - 1));
        }
    }
    ll ans = 0;
    for (int i = min(a, b); i <= n; i++)
    {
        for (int j = min(a, b); j <= m; j++)
        {
            ll mxp = max(p1[i][j], p2[i][j]);
            ll mxq1 = max(q1[1][j + 1], q1[i + 1][1]);
            ll mxq2 = max(q2[1][j + 1], q2[i + 1][1]);
            ans = max(ans, mxp + max(mxq1, mxq2));
        }
    }
    printf("%lld\n", ans);
    return 0;
}
/*Verdict: 100 points

Language: C++

CPU Time usage: 169 ms

Memory usage: 34.5 MB*/
上一篇:152. Maximum Product Subarray 乘积最大子数组


下一篇:CF280D-k-Maximum Subsequence Sum【模拟费用流,线段树】