본문 바로가기
백준

[1463] 1로 만들기

by kmyobin 2023. 1. 2.


https://www.acmicpc.net/problem/1463

 

1463번: 1로 만들기

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

www.acmicpc.net

 

 

오랜만에 다이나믹 프로그래밍 문제!

 

먼저 범위를 설정하고 메모이제이션을 이용해야 하므로 배열을 선언해주었다.

int A[1000001];

A[0]은 안 씀!

 

그리고 직접 써보면서 규칙을 찾아보았다.

1~3은 초기값

직접 배열을 채워보면서 규칙을 찾았다.

1을 빼고 바로 전 값의 A[i-1]을 더하는 경우가 있고,

3을 나누고 A[i/3]을 더하는 경우가 있고,

2를 나누고 A[i/2]을 더하는 경우가 있었다.

 

그리하여 아래와 같은 규칙을 완성하였다.

이를 코드로 작성하면 아래와 같다.

	for (int i = 4; i <= N; i++) {
		int min1 = 0; 
		int min2 = 1000000; 
		int min3 = 1000000;

		min1 = 1 + A[i - 1];
		if (i % 3 == 0) { // 3으로 나누어 떨어지면
			min2 = 1 + A[i / 3];
		}
		if (i % 2 == 0) { // 2로 나누어 떨어지면
			min3 = 1 + A[i / 2];
		}

		A[i] = min(min1, min(min2, min3));
	}

min1, min2, min3을 만들고 이 중에 최솟값을 찾아 A[i]에 넣어주는 알고리즘을 만들었다.

 

min2와 min3이 100000인 이유는 혹여나 3의 배수/2의 배수가 아닐 경우 if문에 들어가지 않기 때문에 임의로 큰 값을 설정해준 것이다.

 

전체 코드는 아래와 같다.

#include <iostream>
#include <cmath>
using namespace std;

int N;
int A[1000001] = { 0, 0, 1, 1, };

int main() {
	ios_base::sync_with_stdio(false);
	cin.tie(NULL);
	cout.tie(NULL);

	cin >> N;

	for (int i = 4; i <= N; i++) {
		int min1 = 0; 
		int min2 = 1000000; 
		int min3 = 1000000;

		min1 = 1 + A[i - 1];
		if (i % 3 == 0) { // 3으로 나누어 떨어지면
			min2 = 1 + A[i / 3];
		}
		if (i % 2 == 0) { // 2로 나누어 떨어지면
			min3 = 1 + A[i / 2];
		}

		A[i] = min(min1, min(min2, min3));
	}

	cout << A[N];
}

 

'백준' 카테고리의 다른 글

[10844] 쉬운 계단 수  (0) 2023.01.04
[11053] 가장 긴 증가하는 부분 수열  (0) 2023.01.03
[1912] 연속합  (0) 2022.11.18
[2263] 트리의 순회  (0) 2022.11.17
[1891] 사분면  (0) 2022.11.14

댓글