✏️기록하는 즐거움
article thumbnail
반응형

1. Link

 

1463번: 1로 만들기

첫째 줄에 1보다 크거나 같고, 106보다 작거나 같은 정수 N이 주어진다.

www.acmicpc.net

 

2. 문제

정수 X에 사용할 수 있는 연산은 다음과 같이 세 가지 이다.X가 3으로 나누어 떨어지면, 3으로 나눈다.X가 2로 나누어 떨어지면, 2로 나눈다.1을 뺀다.정수 N이 주어졌을 때, 위와 같은 연산 세 개를 적절히 사용해서 1을 만들려고 한다. 연산을 사용하는 횟수의 최솟값을 출력하시오.

입력 > 첫째 줄에 1보다 크거나 같고, 106보다 작거나 같은 정수 N이 주어진다.
출력 >첫째 줄에 연산을 하는 횟수의 최솟값을 출력한다.
<javascript />
2

2.2. | 예제 출력 1

<javascript />
1
<javascript />
10

2.4. | 예제 출력 2

<javascript />
3

 

3. 제출

<javascript />
const fs = require("fs"); const input = Number( process.platform === "linux" ? fs.readFileSync("/dev/stdin").toString() : `10` ); const DP = new Array(input + 1).fill(0); // input + 1 개수만큼 0으로 채워진 배열 생성 for (let i = 2; i <= input; i++) { DP[i] = DP[i - 1] + 1; if (i % 2 === 0) { DP[i] = Math.min(DP[i], DP[i / 2] + 1); } if (i % 3 === 0) { DP[i] = Math.min(DP[i], DP[i / 3] + 1); } } console.log(DP[input]);

 

4. 풀이과정

이번 문제는 DP(Dynamic Programming, 동적 계획법)을 사용하면 쉽게 풀 수 있다.

 

DP 배열의 인덱스는 1로 만들기 위한 숫자와 동일하다.

예를 들어, 3을 1로 만들 때 연산을 사용하는 횟수의 최솟값은 DP[3]에 저장되어 있을 것이다.

 

이전에 결과값을 재활용하는 DP의 장점을 이용하기 위해서 2부터 입력값까지의 최소 연산 횟수를 DP 배열에 저장한다.

여기서 1은 이미 1이기 때문에 1을 제외한 2부터 for문을 실행해야 한다.

 

<javascript />
DP[i] = DP[i - 1] + 1;

숫자에 사용할 수 있는 연산은 총 세 가지이다.

그 중 1을 빼는 연산을 미리 해서 DP 배열에 저장한다.

이는 숫자를 1로 만드는 과정에서 2나 3으로 나눈 연산 1을 빼는 연산 중 어느 것이 최소 연산 횟수가 될지 비교하기 위해 저장을 해두는 것이다.

 

예를들어 10에서 1을 빼는 연산을 진행하여 10 - 9 - 3 - 1 의 과정을 거치는 경우,

10의 최소 연산 횟수는 9의 최소 연산 횟수에 1을 더한것과 같다고 볼 수 있다.

 

따라서 위와 같은 식이 성립하게 된다.

 

<javascript />
// 2로 나누어 떨어질 때 if (i % 2 === 0) { DP[i] = Math.min(DP[i], DP[i / 2] + 1); } // 3으로 나누어 떨어질 때 if (i % 3 === 0) { DP[i] = Math.min(DP[i], DP[i / 3] + 1); }

해당 숫자가 2나 3으로 나누어 떨어진다면 1을 뺀 연산을 진행한 기존의 DP[i]와 2나 3으로 나눈 숫자의 최소 연산 횟수에 1을 더한 값과 비교하여 최솟값을 DP[i]에 저장한다.

 

여기서 DP[i / 2]DP[i / 3]에 1을 더해주는 이유는 마찬가지로

9의 최소 연산 횟수는 3의 최소 연산 횟수에 1을 더한 값과 같기 때문이다.

 

5. 개념

5.1. DP(Dynamic Programming)

  • DP의 적용 조건
    • Overlapping Subproblems(겹치는 부분 문제)
    • Optimal Substructure(최적 부분 구조)
  • Overlapping Subproblems
    • DP는 문제의 결과값을 재활용해서 전체 답을 구한다.
    • 따라서 동일한 작은 문제가 반복하여 나타날 경우에 사용 가능하다.
  • Optimal Substructure
    • 부분 문제의 최적 결과 값을 사용해 전체 문제의 최적 결과를 낼 수 있는 경우에 사용한다.
    • 즉, 특정 문제의 최적 결과가 전체 문제에도 동일하게 적용되어 결과가 변하지 않는 경우에 사용 가능하다.
  • DP 예시
    • 피보나치 수열

5.2. Math.min()

  • 매개변수에 주어진 숫자들 중 가장 작은 값을 반환한다.

 


6. Comment

DP를 처음 접해봐서 어떻게 풀어야 할 지 감이 오지 않았었다.

if - else 문을 사용하기엔 코드가 너무 복잡하고 길어질 것 같아 고민을 했지만 역시나 땡처리..!!

DP에 대한 개념을 찾고, 풀이를 보니 조금은 이해가 된 것 같다😄

아직 나아가야 할 길이 많지만 앞으로도 화이팅 !!

 

7. LINK

반응형
profile

✏️기록하는 즐거움

@nor_coding

포스팅이 좋았다면 "좋아요❤️" 또는 "구독👍🏻" 해주세요!