문제
정수 X에 사용할 수 있는 연산은 다음과 같이 세 가지 이다.
- X가 3으로 나누어 떨어지면, 3으로 나눈다.
- X가 2로 나누어 떨어지면, 2로 나눈다.
- 1을 뺀다.
정수 N이 주어졌을 때, 위와 같은 연산 세 개를 적절히 사용해서 1을 만들려고 한다. 연산을 사용하는 횟수의 최솟값을 출력하시오.
입력
출력
첫째 줄에 연산을 하는 횟수의 최솟값을 출력한다.
예제 입력/출력 1
// 입력
2
// 출력
1
예제 입력/출력 2
// 입력
10
// 출력
3
소스코드
다이나믹 프로그래밍(DP, 동적계획법)을 통해 쉽게 해결이 가능한 문제이다. 정수 X에 사용할 수 있는 연산은 1을 뺀 경우, 2로 나누는 경우, 3으로 나누는 경우가 있다.
우선 이 문제를 풀기 위해 정수 X - 1을 했을 경우 정수 X - 1을 해결한 최솟값임을 알 수 있다. 아래와 같이 DP[x] = DP[x-1] + 1의 점화식으로 표현할 수 있다.
1을 빼는 경우가 최솟값일 경우도 있겠지만, 2나 3으로 나눠질 경우 훨씬 더 최솟값에 가까운 수가 될 것이다. 2로 나눠질 경우 아래와 같이 DP[x] = DP[x/2] + 1의 점화식으로 표현할 수 있다.
3으로 나눠질 경우 아래와 같이 DP[x] = DP[x/3] + 1의 점화식으로 표현할 수 있다.
결과적으로 아래와 같은 점화식으로 찾은 값들 중 최솟값을 찾아내면 된다.
- DP[x] = DP[x-1] + 1
- DP[x] = DP[x/2] + 1
- DP[x] = DP[x/3]
const fs = require('fs');
let count = Number(fs.readFileSync('./dev/stdin').toString());
const dp = new Array(count + 1).fill(0);
for (let i = 2; i < dp.length; i++) {
dp[i] = dp[i-1] + 1; // 1을 뺀 경우의 최솟값
if (i % 3 === 0) {
dp[i] = Math.min(dp[i], dp[i/3] + 1) // 3으로 나눴을 경우의 최솟값
}
if (i % 2 === 0) {
dp[i] = Math.min(dp[i], dp[i/2] + 1) // 2로 나눴을 경우의 최솟값
}
}
console.log(dp[count]);
'Computer science > 알고리즘' 카테고리의 다른 글
[백준, node.js] 2193번 "이친수" 문제 해결방법 (0) | 2022.01.20 |
---|---|
[백준, node.js] 11726번 "2xn 타일링" 문제 해결방법 (0) | 2022.01.17 |
[백준, node.js] 10818번 최소, 최대 문제 해결방법 (0) | 2022.01.12 |
[백준: 9093번] 단어 뒤집기 문제 | 자바스크립트(Javascript(JS), Node) (0) | 2021.10.26 |
[백준: 9012번] 괄호 문자열(Parenthesis String, PS) 문제 | 자바스크립트(Javascript(JS), Node) (0) | 2021.10.25 |
이 포스팅은 쿠팡파트너스 활동의 일환으로, 이에 따른 일정액의 수수료를 제공받습니다.