갓우태 2021. 3. 10. 22:19

BOJ ACM Craft : www.acmicpc.net/problem/1005

 

1005번: ACM Craft

첫째 줄에는 테스트케이스의 개수 T가 주어진다. 각 테스트 케이스는 다음과 같이 주어진다. 첫째 줄에 건물의 개수 N 과 건물간의 건설순서규칙의 총 개수 K이 주어진다. (건물의 번호는 1번부

www.acmicpc.net

우선 주어진대로 그림을 그려보니, 그래프가 나왔다.

 

어떻게 이어볼까,, 고민하다가 역으로 이어보니 답이 나왔다.

 

페이지에 있는 테스트케이스를 토대로 그려본다.

 

입력 :

5 10

100000 99999 99997 99994 99990

4 5

3 5

3 4

2 5

2 4

2 3

1 5

1 4

1 3

1 2

4

대략 이런그림이 나온다.

 

내가 필요한 것은 4에 도달하기까지의 시간이다.

 

먼저 목표인 4부터, 무엇을 개발해야 하는지 따져본다.

 

1, 2, 3을 다 개발하면 4를 개발할 수 있는데, 그러면 그때까지의 최대시간은 얼마인가?를 생각해보면

 

점화식을 구할 수 있다.

 

dp[4] = max(dp[1], dp[2], dp[3]) + arr[4]

식을 도출한 뒤, 재귀를 이용해 dp[1], dp[2], dp[3]도 똑같은 방식으로 구할 수 있다.

 

값이 나온 목적지는 배열에 저장해 두고, 나중에 다시 호출되면 써먹는다.

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 <vector>
#include <algorithm>
 
using namespace std;
 
int values[1001];
 
int N, K;
 
int mem[1001];
 
vector<int> v[1001];
 
int recur(int dest)
{
    if (mem[dest] != -1)
    {
        return mem[dest];
    }
 
    int result = 0;
    
    for (int i = 0; i < v[dest].size(); i++)
    {
        result = max(result, recur(v[dest][i]) + values[dest]);
    }
 
    if (v[dest].size() == 0)
    {
        result = values[dest];
    }
 
    mem[dest] = result;
    return result;
}
 
int main()
{
    cin.tie(0);
    ios::sync_with_stdio(0);
 
    int t;
    cin >> t;
    for (int test_case = 0; test_case < t; test_case++)
    {
        cin >> N >> K;
        
        fill_n(mem, N+1-1);
        for (int i = 0; i <= N; i++)
        {
            v[i].clear();
        }
 
        for (int i = 1; i <= N; i++)
        {
            cin >> values[i];
        }
 
        for (int i = 0; i < K; i++)
        {
            int pre, post;
            cin >> pre >> post;
 
            v[post].push_back(pre);
        }
 
        int dest;
        cin >> dest;
 
        cout << recur(dest) << endl;
    }
    return 0;
}
cs
반응형