문제: https://www.acmicpc.net/problem/27971
알고리즘 분류: 너비 우선 탐색, 다이나믹 프로그래밍, 그래프 이론, 그래프 탐색
최단 경로 문제 → BFS
0부터 N까지의 강아지 수를 노드로 생각하고, A마리나 B마리를 추가하는 것을 간선으로 볼 수 있다.
제약 구간에 포함되는 상태는 갈 수 없는 노드이다.
BFS(너비 우선 탐색)를 사용하여 최소 행동 횟수를 찾을 수 있다:
const fs = require('fs');
let input = fs.readFileSync('/dev/stdin').toString().trim().split('\n');
const [N, M, A, B] = input[0].split(' ').map(Number);
// 제약 구간
const restrictedRanges = [];
for (let i = 1; i <= M; i++) {
const [L, R] = input[i].split(' ').map(Number);
restrictedRanges.push([L, R]);
}
// 특정 수가 제약 구간에 포함되는지 검사
const isRestricted = (num) => {
for (const [L, R] of restrictedRanges) {
if (num >= L && num <= R) {
return true;
}
}
return false;
}
// BFS로 최소 행동 횟수 계산
const findMinActions = () => {
// N이 제약 구간에 포함되면 불가능
if (isRestricted(N)) {
return -1;
}
// 방문 배열 (각 강아지 수에 도달하기 위한 최소 행동 횟수 저장)
const visited = new Array(N + 1).fill(-1);
visited[0] = 0; // 초기 상태: 0마리
// BFS를 위한 큐
const queue = [0];
while (queue.length > 0) {
const current = queue.shift();
// N에 도달했으면 최소 행동 횟수 반환
if (current === N) {
return visited[current];
}
// A마리 추가하는 경우
const addA = current + A;
if (addA <= N && !isRestricted(addA) && visited[addA] === -1) {
visited[addA] = visited[current] + 1;
queue.push(addA);
}
// B마리 추가하는 경우
const addB = current + B;
if (addB <= N && !isRestricted(addB) && visited[addB] === -1) {
visited[addB] = visited[current] + 1;
queue.push(addB);
}
}
// N에 도달할 수 없는 경우
return -1;
}
console.log(findMinActions());
BFS의 시간 복잡도: O(V+E)
전체 시간 복잡도: O(N*M)
방문 배열: O(N)
큐: O(N)
전체 공간 복잡도: O(N)
제한 조건(N ≤ 100,000, M ≤ 100)을 충분히 만족