본문 바로가기

BOJ 1463번 : 1로 만들기 본문

BOJ

BOJ 1463번 : 1로 만들기

00rigin 2020. 3. 15. 22:57

문제를 읽어보면 알겠지만, 무조건 큰 수를 작게 만드는 것의 반복이 아니다. 예를 들면

10을 (/2, -1, /2, /2)를 하면, 각 순서마다 가장 작은 값을 뽑아왔지만, (-1, /3, /3) 처럼, 나누는게 우선순위가 아니였다. 즉, /3,/2,-1 순서가 우선순위를 가지지 않는다.

 

그래서 1부터 4까지의 수를 하나씩 해보았다.

 

n = 1, 0번

n = 2, 1번

n = 3, 1번

n = 4,

   1) -1 을 할 경우, n = 3 이 되므로 2번.

   2) /2 를 할 경우, n = 2 가 되므로 2번.

   3) /3 은 불가능.

 

즉, dp[n] 은

(n-1)를 1로 만드는 최소횟수 +1 또는

(n/2)를 1로 만드는 최소횟수 +1 또는

(n/3)을 1로 만드는 최소횟수 +1 이 될 것이다.

 

이런식으로 dp 배열에 인자를 구성하려면, 들어갈 인자는 일단 '값'이 아닌 '횟수'가 될 것이다.

이 것을 점화식으로 바꾼다면, 아래 식으로 구성할 수 있다.

 

dp[i] = (dp[i - 1] + 1); dp[i] = (MIN(dp[i], dp[i / 2] + 1); dp[i] = (MIN(dp[i], dp[i / 3] + 1);

 

<소스코드>

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
#include<iostream>
#include<stdlib.h>
#include<vector>
#define MIN(X,Y) ((X)<(Y)? (X):(Y))
using namespace std;
int main() {
    vector<int> dp(2,0);
    int n = 0;
    cin >> n;
    for (int i = 2; i <= n; i++) {
        dp.push_back(dp[i - 1+ 1);
        if!(i % 2)) dp[i] = (MIN(dp[i], dp[i / 2+ 1));
        if (!(i % 3)) dp[i] = (MIN(dp[i], dp[i / 3+ 1));
    }
    cout << dp[n];
}
http://colorscripter.com/info#e" target="_blank" style="color:#e5e5e5text-decoration:none">Colored by Color Scripter

 

문제 :

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

 

1463번: 1로 만들기

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

www.acmicpc.net

 

'BOJ' 카테고리의 다른 글

BOJ 6603번 : 로또  (0) 2020.03.15
BOJ 1182번 : 부분수열의 합  (0) 2020.03.15
BOJ 2579 : 계단 오르기  (0) 2020.03.15
BOJ 2163번 : 초콜릿 자르기  (0) 2020.03.15
BOJ 2293번 : 동전 1  (0) 2020.03.15
Comments