HDOJ6957 Maximal submatrix【悬线法】

题目链接:HDU6957 Maximal submatrix

动态规划

题意

给定一个 的矩阵,求面积最大的子矩阵,对于该矩阵,满足每列元素是个非递减序列。

题解

首先将原矩阵转化为 01 矩阵,即当 时,。然后用悬线法求这个最大的满足条件的 01 矩阵的面积。

​定义对于当前 a[i][j]up[i][j] 表示所满足条件的最大上界,down[i][j] 表示满足条件的最大下界,len[i][j] 表示矩阵能取到的最大长度,即连续的列数。定义状态转移方程:

​如果当前 b[i][j] = 1,说明 up[i-1][j] 一定是可以取到的一个上界,下界转移同理。然后处理矩阵能取到的最大长度,如果 b[i][j-1] = 1,说明 b[i][j-1] 一定在这个矩阵里,然后再计算前 列区间重叠的部分。 最后 ans = max(ans, len[i][j] * (down[i][j] - up[i][j] + 1))

另外,这题用二维 int 数组会爆空间,用 short 优化即可。

参考代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
#include <iostream>
#include <cstring>
#define FAST ios::sync_with_stdio(false);cin.tie(0),cout.tie(0)
#define endl '\n'
#define debug(x) cout << #x << " = " << (x) << endl
#define mem(a,b) memset(a,b,sizeof(a))
#define max(a,b) ((a)>(b)?(a):(b))
#define min(a,b) ((a)<(b)?(a):(b))
#define rep(i,a,n) for(int i=a;i<=n;++i)
#define per(i,n,a) for(int i=n;i>=a;--i)

using namespace std;

const int maxn = 2e3+5;

int n, m;
short a[maxn][maxn];
bool b[maxn][maxn];
short up[maxn][maxn], down[maxn][maxn], len[maxn][maxn];

void tran() {
mem(b, 0);
rep(i, 1, n) {
rep(j, 1, m) {
if (i == 1) continue;
else if (a[i][j] >= a[i-1][j]) b[i][j] = 1;
}
}
}

void init() {
rep(i, 1, n) {
rep(j, 1, m) {
up[i][j] = i;
down[i][j] = i;
len[i][j] = 1;
}
}
}

int main()
{
FAST;
int t; cin >> t;
while (t--) {
cin >> n >> m;
rep(i, 1, n) {
rep(j, 1, m) {
cin >> a[i][j];
}
}

tran();
init();

rep(j, 1, m) {
rep(i, 2, n) {
if (b[i][j]) up[i][j] = up[i-1][j];
}

per(i, n-1, 1) {
if (b[i+1][j]) down[i][j] = down[i+1][j];
}
}

int ans = m;

rep(j, 1, m) {
rep(i, 1, n) {
if (b[i][j-1]) {
len[i][j] = len[i][j-1] + 1;
up[i][j] = max(up[i][j], up[i][j-1]);
down[i][j] = min(down[i][j], down[i][j-1]);
}
int llen = down[i][j] - up[i][j] + 1;
ans = max(ans, llen * len[i][j]);
}
}
cout << ans << endl;
}
return 0;
}

复杂度分析

  • 时间复杂度:,其中 表示矩阵的大小。
  • 空间复杂度: