이 영역을 누르면 첫 페이지로 이동
hoonDEV 블로그의 첫 페이지로 이동

hoonDEV

페이지 맨 위로 올라가기

hoonDEV

BOJ 12852 - 1로 만들기 2 문제풀이

  • 2020.04.18 15:43
  • 알고리즘/문제풀이

문제를 읽고 이해하기

정수 X에 사용할 수 있는 연산은 다음과 같이 세 가지 이다.

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

정수 N이 주어졌을 때, 위와 같은 연산 세 개를 적절히 사용해서 1을 만들려고 한다. 연산을 사용하는 횟수의 최솟값을 출력하시오.

입력

첫째 줄에 1보다 크거나 같고, 10의 6제곱 보다 작거나 같은 자연수 N이 주어진다.

출력

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

둘째 줄에는 N을 1로 만드는 방법에 포함되어 있는 수를 공백으로 구분해서 순서대로 출력한다. 정답이 여러 가지인 경우에는 아무거나 출력한다.

재정의와 추상화

참고로 이 문제는 clang 컴파일러에서 실행할 경우 메모리 오류가 발생합니다..!

DP를 이용해 문제를 풀 수 있다. DP 구현부는 코드를 보면 이해할 수 있으므로 따로 설명하지 않고, 최소 연산으로 1을 만드는 데까지의 과정을 저장하는 방법에 대해서만 설명하겠다. (중요함)

그 과정은 procedure라는 이름의 배열에 저장하는데, 배열의 인덱스는 현재의 값을 의미하고, 그 배열의 값은 최소 연산을 구현하는 다음 값을 의미한다. 즉, 배열의 값은 (현재의 값 - 1), (현재의 값 / 2), (현재의 값 / 3) 중 하나가 된다.

그리고 DP의 전 과정을 끝낸 후, 최소 연산을 구현하는 과정을 모두 출력할 때, procedure[idx]를 출력하고 idx의 값을 procedure[idx]로 갱신하며 procedure[idx]가 1일 때까지 반복한다. 그 후 1을 출력해주면 끝!

코드 작성

#include <iostream>
using namespace std;

int dp[1000001];
int procedure[1000001];

int process(int start) {
    if (start == 1) { return 0; }

    auto & ref = dp[start];
    if (ref) return ref;

    ref = process(start - 1) + 1;
    procedure[start] = start - 1;
    if (start % 2 == 0) {
        int temp = process(start / 2) + 1;
        if (ref > temp) {
            ref = temp;
            procedure[start] = start / 2;
        }
    }
    if (start % 3 == 0) {
        int temp = process(start / 3) + 1;
        if (ref > temp) {
            ref = temp;
            procedure[start] = start / 3;
        }
    }
    return ref;
}

int main() {
    int n;
    cin >> n;
    cout << process(n) << '\n';
    cout << n << ' ';

    int idx = n;
    while (procedure[idx] != 1) {
        cout << procedure[idx] << ' ';
        idx = procedure[idx];
    }
    cout << 1;
    return 0;
}

'알고리즘 > 문제풀이' 카테고리의 다른 글

BOJ 1074 - Z 문제풀이  (0) 2020.04.18
BOJ 7579 - 앱 문제풀이  (0) 2020.04.18
BOJ 1520 - 내리막 길 문제풀이  (0) 2020.04.18
4월 17일 공부 계획  (0) 2020.04.15
BOJ 11049 - 행렬 곱셈 순서 문제풀이  (0) 2020.04.14

댓글

이 글 공유하기

  • 구독하기

    구독하기

  • 카카오톡

    카카오톡

  • 라인

    라인

  • 트위터

    트위터

  • Facebook

    Facebook

  • 카카오스토리

    카카오스토리

  • 밴드

    밴드

  • 네이버 블로그

    네이버 블로그

  • Pocket

    Pocket

  • Evernote

    Evernote

다른 글

  • BOJ 1074 - Z 문제풀이

    BOJ 1074 - Z 문제풀이

    2020.04.18
  • BOJ 7579 - 앱 문제풀이

    BOJ 7579 - 앱 문제풀이

    2020.04.18
  • BOJ 1520 - 내리막 길 문제풀이

    BOJ 1520 - 내리막 길 문제풀이

    2020.04.18
  • 4월 17일 공부 계획

    4월 17일 공부 계획

    2020.04.15
다른 글 더 둘러보기

정보

hoonDEV 블로그의 첫 페이지로 이동

hoonDEV

  • hoonDEV의 첫 페이지로 이동

검색

메뉴

  • 홈
  • 태그

카테고리

  • 분류 전체보기 (91)
    • 일상 (13)
      • 후기 (1)
      • 계획 (11)
    • 공지사항 (1)
    • 알고리즘 (54)
      • 문제풀이 (53)
      • 이론 (1)
    • 공부 (19)
      • React (0)
      • Angular (5)
      • Java (3)
      • C, C++ (3)
      • JavaScript (6)
      • WEB (2)
    • 디자인 (1)
      • UI, UX (1)
    • 개발 (0)
      • boom (0)

최근 글

인기 글

댓글

공지사항

아카이브

태그

  • 문제풀이
  • 알고리즘
  • javascript
  • 이분탐색
  • 그리디
  • dp
  • 백준
  • es6

나의 외부 링크

정보

훈개발자의 hoonDEV

hoonDEV

훈개발자

블로그 구독하기

  • 구독하기
  • RSS 피드

방문자

  • 전체 방문자
  • 오늘
  • 어제

티스토리

  • 티스토리 홈
  • 이 블로그 관리하기
  • 글쓰기
Powered by Tistory / Kakao. © 훈개발자. Designed by Fraccino.

티스토리툴바