8-1. 1로 만들기

연성·2020년 9월 16일
0

코딩테스트

목록 보기
18/261

다이내믹 프로그래밍) 1로 만들기

1. 문제

정수 X가 주어질 때 정수 X에 사용할 수 있는 연산은 다음과 같이 4가지이다.

  • X가 5로 나누어떨어지면, 5로 나눈다.
  • X가 3으로 나누어떨어지면, 3으로 나눈다.
  • X가 2로 나누어떨어지면, 2으로 나눈다.
  • X에서 1을 뺀다.

정수 X가 주어졌을 때, 연산 4개를 적절히 사용해서 1을 만들려고 한다. 연산을 사용하는 횟수의 최솟값을 출력하시오.

예를 들어, 정수 26이면 다음과 같이 계산하여 3번의 연산이 최솟값이다.

  1. 26 - 1 = 25 (X에서 1을 뺀다.)
  2. 25 / 5 = 5 (5로 나눈다.)
  3. 5 / 5 = 1 (5로 나눈다.)

2. 입력

  • 첫째 줄에 정수 X가 주어진다. (1<=X<=30,000)

3. 출력

  • 첫째 줄에 연산을 하는 횟수의 최솟값을 출력한다.

4. 풀이

  • 비슷한 문제를 많이 풀어봐서 금방 풀었다.
  • 각 정수마다 연산의 최솟값을 배열에 저장하는 방식으로 반복문을 사용한 바텀 업 방식으로 구현하였다.
  • 잠깐 고민한 점이 min 함수를 쓰려고 했는데 배열 기본 값이 0이라는 것이었다.
  • 모든 수는 1을 빼는 연산을 할 수 있기 때문에 배열의 값으로 X-1의 값에 +1 한 값을 최소 연산 횟수로 가정하고 나머지 연산들을 수행하면서 최솟값을 갱신하는 방식으로 구현하였다.

5. 처음 코드와 달라진 점

딱히 없음

6. 코드

#include <iostream>
#include <algorithm>

using namespace std;

int d[30001];

int main() {
	int x;
	cin >> x;

	for (int i = 2; i <= x; i++) {
		d[i] = d[i - 1] + 1;
		if (i % 5 == 0) d[i] = min(d[i], d[i / 5] + 1);
		if (i % 3 == 0) d[i] = min(d[i], d[i / 3] + 1);
		if (i % 2 == 0) d[i] = min(d[i], d[i / 2] + 1);
	}
	cout << d[x] << endl;
}

0개의 댓글