「轉載】張 正錦 菌給的模板 III 動態規劃

第三輯 動態規劃

  • 懸綫法

Hoverline

求解最大子矩陣問題。

C++Luogu P1169
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
#include <iostream>
#include <algorithm>
#include <string.h>
#include <queue>
#include <cstdio>

using namespace std;

int read()
{
char c = ' ';
while(c<'0' || c>'9') c = getchar();
int v = 0;
while(c>='0' && c<='9')
{
v = v * 10 + c - '0';
c = getchar();
}
return v;
}

const int maxn = 2005;
int n,m;
int Map[maxn][maxn],l[maxn][maxn],r[maxn][maxn],up[maxn][maxn];

int main()
{
n = read(), m = read();
for(int i=1; i<=n; i++)
{
for(int j=1; j<=m; j++)
{
Map[i][j] = read();
l[i][j] = r[i][j] = j;
up[i][j] = 1;
}
}
for(int i=1; i<=n; i++)
{
for(int j=2; j<=m; j++)
{
if(Map[i][j] != Map[i][j-1])
l[i][j] = l[i][j-1];
}
}
for(int i=1; i<=n; i++)
{
for(int j=m-1; j>=1; j--)
{
if(Map[i][j+1] != Map[i][j])
r[i][j] = r[i][j+1];
}
}
int ans1 = -0x3f3f3f3f;
int ans2 = -0x3f3f3f3f;
for(int i=1; i<=n; i++)
{
for(int j=1; j<=m; j++)
{
if(i>1 && Map[i][j] != Map[i-1][j])
{
l[i][j] = max(l[i][j],l[i-1][j]);
r[i][j] = min(r[i][j],r[i-1][j]);
up[i][j] = up[i-1][j] + 1;
}
int a = r[i][j] - l[i][j] + 1;
int b = min(a,up[i][j]);
ans1 = max(ans1,b*b);
ans2 = max(ans2,a*up[i][j]);
}
}
cout << ans1 << endl << ans2;
return 0;
}