그냥 하는 노트와 메모장

BOJ 2618 - 경찰차 본문

Solved problems

BOJ 2618 - 경찰차

coloredrabbit 2020. 11. 13. 16:21

BOJ 2618 - 경찰차

[분류 - 다이나믹 프로그래밍]

 

[풀이]

  경찰차 1이 있는 (1, 1)을 1번 사건, 경찰차 2가 있는 (N, N)을 2번 사건, 그리고 나머지 N개의 사건을 3, 4, ..., N+2번 사건이라고 하자. 각 경찰차가 마지막 사건을 처리한 위치가 각각 a, b라고 하면 그 다음 사건을 처리할 때 그 사건의 번호는 max(a, b) + 1이 된다(순차적으로 진행해야 하므로).

 

dp[a][b] = 경찰차 1이 a를 해결했고, 경찰차 2가 b를 해결했을 때 남은 모든 사건을 해결하기 위한 이동 최소 

 

  이제 문제는 꽤 간단해진다.
  당연하게도 그 다음 사건 w(w = max(a, b) + 1)번 사건을 해결하기 위해서는 경찰차 1에 할당할 것인지 경찰차 2에 할당할 것인지 두 가지밖에 없다.

  dist(n1, n2)를 n1번 사건과 n2번 사건의 거리라고 정의할 때,
1. 경찰차 1에 할당하는 경우
  dp[w][b] + dist(a, w)를 부분 문제로 둘 수 있다.
2. 경찰차 2에 할당하는 경우
  dp[a][w] + dist(b, w)를 부분 문제로 둘 수 있다.

  위 경우를 모두 고려하고 최소값을 쫓아가도록 추적하는 로직을 짜주면 된다. 추적할 때 배열을 따로 둬서 저장해도 되고, 아니면 재귀를 통해 구현해도 된다.

#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int MAX_W = 1002;
int N, W, pos[MAX_W][2], dp[MAX_W][MAX_W];
pair<int, int> trace[MAX_W][MAX_W];
int rec(int a, int b) {
    if (a == W || b == W) return 0;
    int& ret = dp[a][b];
    if (ret != -1) return ret;
    int w = max(a, b) + 1;
    ret = rec(w, b) + abs(pos[a][0] - pos[w][0]) + abs(pos[a][1] - pos[w][1]);
    trace[a][b] = { w, b };
    if (ret > rec(a, w) + abs(pos[b][0] - pos[w][0]) + abs(pos[b][1] - pos[w][1])) {
        ret = rec(a, w) + abs(pos[b][0] - pos[w][0]) + abs(pos[b][1] - pos[w][1]);
        trace[a][b] = { a, w };
    }
    return ret;
}
int main() {
    memset(dp, -1, sizeof dp);
    int i, a, b;
    scanf("%d%d", &N, &W);
    pos[0][0] = pos[0][1] = 1;
    pos[1][0] = pos[1][1] = N;
    W++;
    for (i = 2; i <= W; i++) scanf("%d%d", &pos[i][0], &pos[i][1]);
    printf("%d\n", rec(0, 1));
    for (a = 0, b = 1, i = 2; i <= W; i++) {
        auto nxt = trace[a][b];
        printf("%d\n", nxt.first == a ? 2 : 1);
        a = nxt.first, b = nxt.second;
    }
    return 0;
}

'Solved problems' 카테고리의 다른 글

BOJ 2638 - 치즈  (0) 2020.11.13
BOJ 1053 - 팰린드롬 공장  (0) 2020.11.13
BOJ 1600 - 말이 되고픈 원숭이  (0) 2020.11.13
BOJ 8902 색상의 길이  (0) 2020.07.01
BOJ 1226 국회  (0) 2020.06.25
Comments