这题其实并不难,比赛的时候自己脑子就是转不动==
题目大意:
有一个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*/