본문 바로가기

백준/DP

백준 1513 - 경로 찾기

728x90

icpc.me/1513

 

제약이 까다로워 애를 먹었던 dp 문제이다.

 

오락실의 방문 순서는 순증가여야 한다는 점과 오락실은 출발점과 도착점에도 존재할 수 있다는 것이 문제를 어렵게 만든다.

 

다만 도시의 크기는 50 * 50이기 때문에 메모리를 넉넉하게 사용할 수 있다. 제약을 고려하여 사차원 테이블에 다음 점화식을 세울 수 있다.

 

$f(row, \, column, \, last, \, cnt) = $ row 행 column 열에서 마지막으로 방문한 오락실의 순서 번호가 last일 때 남은 오락실 방문 가능 횟수 cnt

 

map을 사용하여 오락실의 순서 번호를 저장한 뒤, 점화식으로 탑 다운 dp를 돌리면서 cnt번의 방문으로 학교에 도착할 수 없거나 방문했었던 오락실보다 순서 번호가 더 낮은 오락실에 방문하는 경우를 걸러주면 효과적으로 답을 구할 수 있다.

 

전체 코드

더보기
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
#include <bits/stdc++.h>
 
#define mod 1000007
 
using namespace std;
using pii = pair<intint>;
 
int n, m, v;
int dp[51][51][51][51];
map<pii, int> funidx;
 
int memo(int r, int c, int last, int cnt);
 
int main()
{
    memset(dp, -1sizeof dp);
    cin.tie(0); ios::sync_with_stdio(false);
 
    cin >> n >> m >> v;
 
    for (int i = 1; i <= v; ++i)
    {
        int a, b;
        cin >> a >> b;
 
        funidx[{a, b}] = i;
    }
 
    for (int i = 0; i <= v; ++i)
        cout << memo(110, i) << ' ';
}
 
int memo(int r, int c, int last, int cnt)
{
    int &ret = dp[r][c][last][cnt];
 
    if (ret != -1)
        return ret;
 
    ret = 0;
 
    if (funidx.count({r, c}))
    {
        if (last > funidx[{r, c}])
            return ret;
 
        if (r == n && c == m && cnt == 1)
            ret = 1;
 
        if (r < n && cnt > 0)
            ret = (ret + memo(r + 1, c, funidx[{r, c}], cnt - 1)) % mod;
        if (c < m && cnt > 0)
            ret = (ret + memo(r, c + 1, funidx[{r, c}], cnt - 1)) % mod;
    }
    else
    {
        if (r == n && c == m && !cnt)
            ret = 1;
 
        if (r < n)
            ret = (ret + memo(r + 1, c, last, cnt)) % mod;
        if (c < m)
            ret = (ret + memo(r, c + 1, last, cnt)) % mod;
    }
 
    return ret;
}
cs

 

728x90

'백준 > DP' 카테고리의 다른 글

백준 1480 - 보석 모으기  (0) 2020.12.23
백준 2216 - 문자열과 점수  (0) 2020.12.04
[ICPC] 백준 2159 - 케익 배달  (0) 2020.12.01
백준 11051 - 이항 계수 2  (0) 2020.11.30
[ICPC] 백준 4811 - 알약  (0) 2020.11.30