BOJ : https://www.acmicpc.net/problem/2186
github : https://github.com/junho0956/Algorithm/blob/master/2186/2186/%EC%86%8C%EC%8A%A4.cpp
처음에는 BFS, DFS 로 둘다 탐색해보았는데
전부다 시간초과가 되서 멘탈이 나갔던 문제였다. 마침 설날이라 놀고싶기도 했고,, ??
처음에 bfs 에 의해 시간초과가 발생해서
시도해본게 dfs 로 첫 발생지점에 대한 dp 였다.
2중포문을 돌면서 첫 알파벳을 찾는 순간 dp를 초기화하고
이 부분에 대한 dfs 를 돌면서 탐색하지 않아도 되는 부분은 줄여나가는 식으로 했었다.
역시 시간초과였다.
그래서 다른방법을 생각해보았다.
통째로 dp를 적용할 수 있을까?
그래서 생각한게 3차원 배열의 dp였다
원래 dfs 를 적용했을때는 100*100 dp 를 사용했는데
3차원 배열을 사용하면 인덱스별로 dp 를 적용할 수 있을 것 같았다.
그래서 사용한 배열이 100*100*80 dp 이고
** 현재 탐색하고있는 알파벳 부분의 인덱스를 알고 있을 때 dp 값이 존재하지 않는다면 탐색,
** 존재한다면 리턴 하는 식으로 구현해보았다.
|
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
|
// bfs 로 풀어보니 시간초과가 발생한다
// dfs 로 풀게되면 시간초과가 발생하긴 하는데, dp 같은 느낌의 방법을
// 적용해볼 수 있을 것 같다.
#include <iostream>
#include <string>
using namespace std;
// 최대길이가 80 이라고했으니 80에 대한 dp 배열을 잡는다.
// 80 의 의미는 임의의 (y,x) 에 도착했을 때
// 현재 문자열의 인덱스 중 몆번째 인덱스를 탐색하는지 알고있다면,
// 이때 dp 배열이 초기화상태가 아니라면 이미 이 부분은 탐색된 것이니
// 탐색을 중단하고 값을 가져간다는 느낌으로 간다.
int dp[100][100][80];
char arr[100][100];
int mx[4] = { -1,1,0,0 };
int my[4] = { 0,0,1,-1 };
int N, M, K;
string ans;
int solve(string str, int y, int x, int idx) {
if (dp[y][x][idx] != -1) return dp[y][x][idx];
if (str.size() >= ans.size()) return 1;
dp[y][x][idx] = 0;
for (int i = 0; i < 4; i++) {
int yy = y, xx = x;
for (int j = 1; j <= K; j++) {
yy += my[i];
xx += mx[i];
if (yy >= 0 && xx >= 0 && yy < N && xx < M && arr[yy][xx] == ans[idx+1]) {
dp[y][x][idx] += solve(str + ans[idx+1], yy, xx, idx + 1);
}
}
}
return dp[y][x][idx];
}
int main() {
ios::sync_with_stdio(0), cin.tie(0), cout.tie(0);
cin >> N >> M >> K;
for (int i = 0; i < N; i++)
for (int j = 0; j < M; j++)
cin >> arr[i][j];
cin >> ans;
int total = 0;
string f;
f.push_back(ans[0]);
// 밑부분에서 solve(f,i,j,0) 을 할때 dp return 을 하지 않기 때문에
// 일부러 -1 로 초기화 해주었다.
for (int i = 0; i < N; i++) for (int j = 0; j < M; j++) for (int k = 0; k < 80; k++) dp[i][j][k] = -1;
for (int i = 0; i < N; i++) {
for (int j = 0; j < M; j++) {
if (arr[i][j] == ans[0]) {
total += solve(f, i, j, 0);
}
}
}
cout << total;
return 0;
}
http://colorscripter.com/info#e" target="_blank" style="color:#e5e5e5text-decoration:none">Colored by Color Scripter
|
'algorithm > BOJ' 카테고리의 다른 글
| BOJ 5014번 스타트링크 (0) | 2020.01.31 |
|---|---|
| BOJ 3108번 로고 (0) | 2020.01.31 |
| BOJ 2251번 물통 (0) | 2020.01.24 |
| BOJ 1525번 퍼즐 (0) | 2020.01.24 |
| BOJ 9019번 DSLR (0) | 2020.01.23 |