[백준] 10653번 마라톤 2 (C++)

2025. 9. 3. 18:35·Algorithm
728x90

https://www.acmicpc.net/problem/10653

 

 

 

이 문제는 N개의 체크포인트가 존재하고 각 체크포인트마다 x, y좌표가 주어지며 K만큼 건너뛸 수 있는 횟수가 주어질때
도착 지점까지 K만큼 건너뛰었을때 최소 거리를 출력하는 문제이다.

 

문제를 보고 최단거리라고 생각을 해서 다익스트라 알고리즘을 사용하면 되지 않을까 싶었다.

하지만 구현을 하다 보니 건너뛴 횟수를 카운트를 해준다 한들 내가 이전에 어느 지점에서 건너 뛰었는지에 대한 정보들을 다 기록해 줘야 하기 때문에

 

다익스트라 알고리즘으로 구현하기는 힘들다고 판단하였다.

 

이후 어차피 N개의 체크포인트를 순서대로 방문해야 하기 때문에 순서성이 존재하여 dfs, dp를 사용하여 풀 수 있다고 생각했다.

 

이후에 dp를 점화식을 사용하는 부분에서 굉장히 오랜 시간이 걸렸다.

 

 

정답코드

#include <bits/stdc++.h>
using namespace std;
typedef pair<int, int> pii;
typedef long long ll;
#define endl "\n"
#define MAX 1e9

struct coordinate {
    int x;
    int y;
    int r;
};

int dx[] = {-1, 1, 0, 0, 1, -1, -1, 1};
int dy[] = {0, 0, -1, 1, -1, 1, -1, 1};
int N, K;
vector<pii> v;

int dist(int a, int b, vector<pii> &vec) {
    return abs(vec[a].first - vec[b].first) + abs(vec[a].second - vec[b].second);
}

void solve() {
    vector<vector<int>> dp(N, vector<int>(K+1, MAX));
    dp[0][0] = 0;

    for(int i = 1; i < N; i++) {
        for(int j = 0; j < i && j <= K; j++) {
            for(int k = 0; k <= j; k++) {
                dp[i][j] = min(dp[i][j], dp[i-k-1][j-k] + dist(i-k-1, i, v));
            }
        }
    }

    int answer = MAX;
    for(int i = 0; i <= K; i++) {
        answer = min(answer, dp[N-1][i]);
    }

    cout << answer;
}

void input() {
    cin >> N >> K;

    for(int i = 0; i < N; i++) {
        int a, b;
        cin >> a >> b;
        v.push_back({a, b});
    }
}

int main() {
    ios::sync_with_stdio(0);
    cin.tie(0), cout.tie(0);

    input();
    solve();
}

 

 

풀이과정을 하나씩 살펴보면

	vector<vector<int>> dp(N, vector<int>(K+1, MAX));
    dp[0][0] = 0;

    for(int i = 1; i < N; i++) {
        for(int j = 0; j < i && j <= K; j++) {
            for(int k = 0; k <= j; k++) {
                dp[i][j] = min(dp[i][j], dp[i-k-1][j-k] + dist(i-k-1, i, v));
            }
        }
    }

    int answer = MAX;
    for(int i = 0; i <= K; i++) {
        answer = min(answer, dp[N-1][i]);
    }

dp 배열을 미리 할당해 놓고 INF값으로 초기화 하였으며 시작점에서부터 최소값을 갱신할거기 때문에 시작점은 0으로 놓았다.

 

이후 점화식을 설명하면 i는 체크포인트를 나타내며 j는 건너뛴 횟수이며 k는 그 건너뛴 횟수중 이전에 건너뛴 개수를 나타낸다.

따라서 j는 체크포인트보다 작아야하며 K보다는 작거나 같아야 한다.

 

int dist(int a, int b, vector<pii> &vec) {
    return abs(vec[a].first - vec[b].first) + abs(vec[a].second - vec[b].second);
}

 

dist 함수를 살펴보면 a, b가 나타내는 것은 건너뛰었을때 도착한 지점에서 i(즉 현재 바라보는 체크포인트 좌표) 까지의 맨하탄 거리를 나타낸다.

시간복잡도는 O(N^3) 보다는 훨씬 작다고 생각하였으며 j가 안되는 경우가 많기 때문에 저거보다는 훨씬 작다고 생각한다.

 

 

회고록

점화식 세우는게 굉장히 까다로웠던 문제이다. 처음엔 2중 for문으로 풀릴 수 있지 않을까 생각했는데 다익스트라 구현때처럼

이전에 건너뛰었던 위치를 기록했어야 하기 때문에 3중 for문으로 구현하였다.

728x90
저작자표시 (새창열림)

'Algorithm' 카테고리의 다른 글

[백준] 1411번 비슷한 단어 (C++)  (0) 2025.09.05
[백준] 3078번 좋은 친구 (C++)  (0) 2025.09.04
[백준] 14888번 연산자 끼워넣기 (C++)  (0) 2025.09.02
[백준] 11502번 세 개의 소수 문제 (C++)  (0) 2025.09.01
[백준] 23326번 홍익 투어리스트 (C++)  (0) 2025.08.31
'Algorithm' 카테고리의 다른 글
  • [백준] 1411번 비슷한 단어 (C++)
  • [백준] 3078번 좋은 친구 (C++)
  • [백준] 14888번 연산자 끼워넣기 (C++)
  • [백준] 11502번 세 개의 소수 문제 (C++)
쿨쿨.
쿨쿨.
  • 쿨쿨.
    All of the life
    쿨쿨.
  • 전체
    오늘
    어제
    • 분류 전체보기 (284) N
      • Programming (51) N
        • C, C++ (18)
        • Python (6)
        • Java (1)
        • HTML,CSS,JS (3)
        • SQL(DB) (13)
        • SpringBoot (7) N
        • Android (2)
        • CI,CD (1)
      • Algorithm (173)
        • Review (4)
      • Security (14)
        • WebHacking (3)
        • Websecurity (11)
      • OS (19)
        • Linux (12)
        • Mac os (2)
      • 머신러닝 (1)
      • CS(Computer Science) (12)
        • 컴퓨터 네트워크 (3)
        • 컴퓨터 구조 (1)
        • 인공지능 (8)
      • Docker (2) N
      • Dev Book Review (3)
        • Clean Code (1)
        • Effective Java (0)
        • Real MySQL (2)
      • SWM (1)
      • Review (6)
      • AWS (2)
  • 블로그 메뉴

    • 홈
    • 태그
    • 방명록
  • 링크

  • 공지사항

  • 인기 글

  • 태그

    우선순위 큐
    에라토스테네스의 체
    DP
    트리
    DFS
    투포인터
    그리디
    비트마스킹
    우선순위큐
    깊이우선탐색
    코딩
    백준
    c언어
    wargame
    Bandit
    WebSecurity
    다이나믹 프로그래밍
    BFS
    백트래킹
    구현
    재귀
    이분탐색
    다익스트라
    누적합
    Leviathan
    그래프 이론
    linux
    브루트포스
    정렬
    시뮬레이션
  • 최근 댓글

  • 최근 글

  • 250x250
  • hELLO· Designed By정상우.v4.10.6
쿨쿨.
[백준] 10653번 마라톤 2 (C++)
상단으로

티스토리툴바