版权声明:欢迎借鉴,谢绝抄搬。 https://blog.csdn.net/Gx_Man_VIP/article/details/88647276
题目大意:
分析:
因为权值非负,一个矩阵的权值肯定≥其子矩阵。那么建立一个堆,
开始把所有最小的和谐矩阵加入堆,每次从堆中取出最小的和谐矩阵,同时扩展出最多四个新的和谐矩阵(上下左右多一行或一列),注意判重,重复
次即可。
然后注意一下每个矩阵拓展的时候只需要→↓或者←↑ 2个方向即可,4个方向会炸
代码:
#include <iostream>
#include <cstring>
#include <cmath>
#include <queue>
#include <map>
#include <cstdio>
#include <algorithm>
#define JR(i, j) (i-1)*m+j
#define N 1005
using namespace std;
typedef long long ll;
int n, m, mina, minb, K;
ll sum[N][N];
struct Node {
int x1, y1, x2, y2;
ll Get_Sum() const {
return sum[x2][y2] - sum[x1 - 1][y2] -sum[x2][y1 - 1] + sum[x1 - 1][y1 - 1];
}
friend bool operator < (Node aa, Node bb)
{
return aa.Get_Sum() > bb.Get_Sum();
}
Node(){};
Node(int a, int b, int c, int d)
{
x1 = a, y1 = b, x2 = c, y2 = d;
}
};
priority_queue <Node> Q;
map <pair<int, int>, int> id;
inline void Insert(Node &A)
{
int x1 = A.x1, y1 = A.y1, x2 = A.x2, y2 = A.y2;
if (x2 < n && !id[make_pair(JR(x1, y1), JR(x2 + 1, y2))])
Q.push(Node(x1, y1, x2 + 1, y2)), id[make_pair(JR(x1, y1), JR(x2 + 1, y2))] = 1;
if (y2 < m && !id[make_pair(JR(x1, y1), JR(x2, y2 + 1))])
Q.push(Node(x1, y1, x2, y2 + 1)), id[make_pair(JR(x1, y1), JR(x2, y2 + 1))] = 1;
}
int main()
{
scanf("%d %d %d %d %d", &n, &m, &mina, &minb, &K);
for (int i = 1; i <= n; i++)
for (int j = 1; j <= m; j++)
{
int x; scanf("%d", &x),
sum[i][j] = (ll)sum[i - 1][j] + sum[i][j - 1] - sum[i - 1][j - 1] + x;
}
for (int i = 1; i <= n - mina + 1; i++)
for (int j = 1; j <= m - minb + 1; j++) Q.push(Node(i, j, i + mina - 1, j + minb - 1));
for(int i = 1; i < K; i++)
{
if (!Q.size())
{
printf("-1\n");
return 0;
}
Node u = Q.top(); Q.pop();
Insert(u);
}
if (!Q.size()) printf("-1\n"); else printf("%lld\n", Q.top().Get_Sum());
return 0;
}