一道有点套路化的网格图上$DP$QwQ

我们用$f_{min}[i][j][0]$表示线头在$(i, j)$这个点的时候,线的方向朝,我们能取到的最小的拐弯次数、用$f_{min}[i][j][1]$表示线头在$(i, j)$这个点的时候,显得方向朝,能够取到的最小的拐弯次数

同理,我们用$f_{max}[i][j][0]$与$f_{max}[i][j][1]$表示线头在$(i, j)$位置是线朝下和朝右能够取到的最大的拐弯次数。

接下来,对于有障碍的点,我们直接不处理

显然,答案分别为$\max(f_{max}[n][m][0], f_{max}[n][m][1])$与$\min(f_{min}[n][m][0], f_{min}[n][m][1])$

接下来,我们就可以写出状态转移方程辣

$f_{min}[i][j][0] = \min(f_{min}[i - 1][j][0], f_{min}[i - 1][j][1] + 1)$
$f_{min}[i][j][1] = \min(f_{min}[i][j - 1][1], f_{min}[i][j - 1][0] + 1)$

$f_{max}[i][j][0] = \max(f_{max}[i - 1][j][0], f_{max}[i - 1][j][1] + 1)$
$f_{max}[i][j][1] = \max(f_{max}[i][j - 1][1], f_{max}[i][j - 1][0] + 1)$

注意初始化,$f_{min}$初始化为$\inf$,$f_{max}$初始化为-1,注意边界~~

上代码QwQ

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
// Sooke bless me.
// LJC00118 bless me.
#include<bits/stdc++.h>

#define INF 1000000000
#define ll long long

int Inp(){
char c = getchar();
int Neg = 1;
while(c < '0' || c > '9'){
if(c == '-')
Neg = -1;
c = getchar();
}
int Sum = 0;
while(c >= '0' && c <= '9'){
Sum = ((Sum << 3) + (Sum << 1)) + c - '0';
c = getchar();
}
return Neg * Sum;
}

int f_max[1010][1010][3];
int f_min[1010][1010][3];
char s[1010][1010];

int main(){
int n = Inp();
int m = Inp();
for(int i = 1; i <= n; i++)
scanf("%s", s[i] + 1);
for(int i = 0; i <= n; i++)
for(int j = 0; j <= m; j++){
f_max[i][j][0] = f_max[i][j][1] = -1;
f_min[i][j][0] = f_min[i][j][1] = INF;
}
for(int i = 1; i <= n; i++)
for(int j = 1; j <= m; j++){
if(s[i][j] == '#')
continue;
if(i == 1 && j == 1){
f_max[1][1][0] = f_max[1][1][1] = 0;
f_min[1][1][0] = f_min[1][1][1] = 0;
continue;
}
f_min[i][j][0] = std::min(f_min[i - 1][j][0], f_min[i - 1][j][1] + 1);
f_min[i][j][1] = std::min(f_min[i][j - 1][1], f_min[i][j - 1][0] + 1);

f_max[i][j][0] = std::max(f_max[i - 1][j][0], f_max[i - 1][j][1] + 1);
f_max[i][j][1] = std::max(f_max[i][j - 1][1], f_max[i][j - 1][0] + 1);

}

if(std::min(f_min[n][m][0], f_min[n][m][1]) == INF){
printf("-1");
return 0;
}
printf("%d %d", std::max(f_max[n][m][0], f_max[n][m][1]) - 1, std::min(f_min[n][m][0], f_min[n][m][1]));
}

 评论