Gym-101972G
Minimax
题目大意
定义一个矩阵的beauty值为矩阵中的最大元素
给出一个m*n的矩阵,从中删除一行一列,将矩阵分成四个象限,每个象限有一个beauty值,问怎样分能够使得四个象限beauty值得最大与最小值之差最小,求这个最小值。Time : 2500 ms
Memory: 262144 kB
解题思路及分析
从四个方向开始DP,记录四个方向子矩阵的beauty值,然后枚举每一行每一列,更新最小值
AC代码
#include <bits/stdc++.h>
typedef long long llong;
typedef long double ldouble;
using namespace std;
const int N = 500 + 10;
int n, m;
int a[N][N];
int lu[N][N], ru[N][N], ld[N][N], rd[N][N];
int main() {
#ifdef LOCAL
freopen("in.in", "r", stdin);
freopen("out.out", "w", stdout);
#endif
int T; scanf("%d", &T);
while (T--) {
scanf("%d%d", &n, &m);
for (int i = 1; i <= n; i++) {
for (int j = 1; j <= m; j++) {
scanf("%d", &a[i][j]);
}
}
for (int i = 0; i <= n; i++) {
lu[i][0] = ru[i][0] = ld[i][0] = rd[i][0] = 0;
lu[i][m + 1] = ru[i][m + 1] = ld[i][m + 1] = rd[i][m + 1] = 0;
}
for (int j = 0; j <= m; j++) {
lu[0][j] = ru[0][j] = ld[0][j] = rd[0][j] = 0;
lu[n + 1][j] = ru[n + 1][j] = ld[n + 1][j] = rd[n + 1][j] = 0;
}
// lu
for (int i = 1; i <= n; i++) {
for (int j = 1; j <= m; j++) {
lu[i][j] = max(a[i][j], max(lu[i][j - 1], lu[i - 1][j]));
}
}
// ru
for (int i = 1; i <= n; i++) {
for (int j = m; j > 0; j--) {
ru[i][j] = max(a[i][j], max(ru[i][j + 1], ru[i - 1][j]));
}
}
// ld
for (int i = n; i > 0; i--) {
for (int j = 1; j <= m; j++) {
ld[i][j] = max(a[i][j], max(ld[i][j - 1], ld[i + 1][j]));
}
}
// rd
for (int i = n; i > 0; i--) {
for (int j = m; j > 0; j--) {
rd[i][j] = max(a[i][j], max(rd[i][j + 1], rd[i + 1][j]));
}
}
int ans = 1e9 + 10;
for (int i = 2; i < n; i++) {
for (int j = 2; j < m; j++) {
int mx = max(lu[i - 1][j - 1], max(ru[i - 1][j + 1], max(ld[i + 1][j - 1], rd[i + 1][j + 1])));
int mi = min(lu[i - 1][j - 1], min(ru[i - 1][j + 1], min(ld[i + 1][j - 1], rd[i + 1][j + 1])));
ans = min(ans, mx - mi);
}
}
printf("%d\n", ans);
}
return 0;
}