Algorithm

[BOJ] 징검다리 건너기 (small) 22869번 C++

따봉치치 2025. 1. 19. 14:46

 

문제

 N개의 돌이 일렬로 나열 되어 있다. N개의 돌에는 왼쪽부터 차례대로 수 A1A2...Ai...AN로 부여되어 있다. 가장 왼쪽에 있는 돌에서 출발하여 가장 오른쪽에 있는 돌로 건너가려고 한다.

  1. 항상 오른쪽으로만 이동할 수 있다.
  2.  i번째 돌에서 j(i<j)번째 돌로 이동할 때 (j−i) × (1 + |Ai−Aj|) 만큼 힘을 쓴다.
  3. 돌을 한번 건너갈 때마다 쓸 수 있는 힘은 최대 K이다.

이때, 가장 왼쪽 돌에서 출발하여 가장 오른쪽에 있는 돌로 건너갈 수 있는지 구해보자.

입력

첫 번째 줄에 돌의 개수 N와 쓸 수 있는 최대 힘 K가 공백으로 구분되어 주어진다.

두 번째 줄에는 N개의 돌의 수 Ai가 공백으로 구분되어 주어진다.

출력

가장 오른쪽에 있는 돌로 이동할 수 있다면 YES를 출력한다. 만약 이동하지 못하는 경우에는 NO를 출력한다.

 

접근 방식

 

가장 간단하게 이중 반복문을 돌면서 현재 자리에서 건너갈 수 있는 돌인지 확인하려고 했다

이때, 시작 돌 또한 이전에 이동될 수 있는 돌인지 확인해줘야 한다

 

즉, 1 2 3 4 5 번째 돌중에서

3 -> 5로 건널수 있는지 확인 이전에 1 -> 3 혹은 2 -> 3이 선행되어야 한다는 말이다!

 

따라서, N번째 돌이 접근가능하면 YES를 접근 가능하지 않고 0이라면 NO를 출력해주었다

 

 

코드

#include<bits/stdc++.h>
using namespace std;

int main() {
    int N,K; cin>>N>>K;
    vector<int> v(N+1);
    v[0] = 0;
    for(int i=1; i<=N; i++) cin>>v[i];

    int dp[5002] = {0};
    dp[1] = 1;


    for(int i=1; i<=N; i++) {
        if(dp[i] == 0) continue;
        for(int j=i+1; j<=N; j++) {
            int tmp = (j-i) *(1 + abs(v[i] - v[j]));
            if(tmp <= K) dp[j] = dp[i-1] + 1;
        }
    }
    string ans = dp[N] == 0 ? "NO" : "YES";
    cout<<ans;
    

}