알고리즘 연습/백준
[BOJ22869 징검다리 건너기(small)] 다이나믹 프로그래밍 dp
_h.j
2024. 5. 18. 00:10
728x90
1. Top Down, 재귀
N에 도달 가능 여부만 판단한다.
#include <iostream>
#include <cstring>
#include <cmath>
#define MAX_N 5001
using namespace std;
int N, K;
int e[MAX_N], dp[MAX_N];
// top - down
// 도달 가능 여부만 확인하면 된다
// 갈 수 있으면 바로 끝
// 2중 for 사용 가능
int canGo(int target) {
int& ret = dp[target];
if (ret != -1) return ret;
ret = 0; //0으로 설정, 일단 못간다 세팅
// i -> target으로 이동
for (int i = 0; i < target; i++) {
int power = (target - i) * (1 + abs(e[target] - e[i]));
if (power <= K) {
if (canGo(i)) {
return ret = 1; // 1
}
}
}
return ret; // 0
}
int main() {
ios::sync_with_stdio(0); cin.tie(0); cout.tie(0);
cin >> N >> K;
for (int i = 0; i < N; i++) cin >> e[i];
memset(dp, -1, sizeof(dp)); //-1 : 아직 안봤다.
dp[0] = 1; // 갈 수 있다.
cout << (canGo(N-1) ? "YES" : "NO");
return 0;
}
2. Bottom Up , 2 중 for
#include <iostream>
#include <cstring>
#include <cmath>
#define MAX_N 5001
#define INF 0x7f7f7f7f
using namespace std;
int N, K;
int e[MAX_N];
int dp[MAX_N];
int main() {
ios::sync_with_stdio(0); cin.tie(0); cout.tie(0);
cin >> N >> K;
for (int i = 1; i <= N; i++) cin >> e[i];
memset(dp, INF, sizeof(dp));
dp[0] = dp[1] = 0;
for (int i = 1; i <= N - 1; i++) {
for (int j = i + 1; j <= N; j++) {
int power = (j - i) * (1 + abs(e[j] - e[i]));
if (power > K || dp[i] == INF) continue;
dp[j] = min(power, dp[j]);
}
}
cout << ((dp[N] == INF) ? "NO" : "YES");
return 0;
}
목표 지점에 도달 가능 여부만 판단하면 되기 때문에 1번 코드가 더 효율적이다.
728x90