题解 洛谷P5003 跳舞的线-乱拐弯

一道有点套路化的网格图上DPDPQwQ

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

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

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

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

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

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

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

注意初始化,fminf_{min}初始化为inf\inffmaxf_{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]));
}

QQ

|

Codeforces

|

Luogu

|

Github
本站由 Hexo 驱动,使用 Azurus 作为主题。