danbibibi
article thumbnail

문제

문제 바로가기> BOJ 12852번: 1로 만들기 2

 

12852번: 1로 만들기 2

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

www.acmicpc.net

 

풀이

 

처음엔, 아래와 같이 dp 배열을 구축한 후,

구축된 배열에서 역추적해가며 N을 1로 만드는 방법에 포함되어 있는 수를 출력해주었다.

이 때는 ,, dp[1] = 0을 1로 초기화 해줘서 앞에서 리턴하게 하고 암튼 그랬지만,

전반적인 역추적 아이디어는 아래와 같았다.

 

그런데 사실 dp 배열을 만드는 과정에서 배열을 하나 더 만들어서 그 이전 값을 저장하는 dp 배열을 만든다면??!!

더 편하게 "N을 1로 만드는 방법에 포함되어 있는 수"를 구할 수 있다!!

dp 배열이 업데이트 됨에 따라 그 값을 담고 있는 배열도 함께 업데이트 될 테니까 ....!!

#include <iostream>
#define MAX 1000001
using namespace std;

int N;
int dp[MAX], before[MAX];

int main()
{
    ios_base::sync_with_stdio(0);
    cin.tie(0);
    cin >> N;

    dp[1] = before[1] = 0;
    for (int i = 2; i <= N; i++)
    {
        dp[i] = dp[i - 1] + 1;
        before[i] = i - 1;
        if (i % 2 == 0 && dp[i / 2] + 1 < dp[i])
        {
            dp[i] = dp[i / 2] + 1;
            before[i] = i / 2;
        }
        if (i % 3 == 0 && dp[i / 3] + 1 < dp[i])
        {
            dp[i] = dp[i / 3] + 1;
            before[i] = i / 3;
        }
    }
    cout << dp[N] << "\n";
    while (N != 0)
    {
        cout << N << " ";
        N = before[N];
    }
}

 

사실 저 위에서 for문 말고 while문으로 돌면서, N/3, N/2, N-1을 그때 그때 봐주며 계산해도 된다.

그럼 메모리 더 적게 쓰고, 시간은 똑같기 때문!! 아래가 내가 짠 코드 중 제일 효율적인 코드였당

#include <iostream>
#define MAX 1000001
using namespace std;

int N;
int dp[MAX];

int main()
{
    ios_base::sync_with_stdio(0);
    cin.tie(0);
    cin >> N;

    dp[1] = 0;
    for (int i = 2; i <= N; i++)
    {
        dp[i] = dp[i - 1] + 1;
        if (i % 2 == 0 && dp[i / 2] + 1 < dp[i])
            dp[i] = dp[i / 2] + 1;

        if (i % 3 == 0 && dp[i / 3] + 1 < dp[i])
            dp[i] = dp[i / 3] + 1;
    }
    cout << dp[N] << "\n";

    int nextCnt = dp[N] - 1;
    while (N != 0)
    {
        cout << N << " ";
        if (N % 3 == 0 && dp[N / 3] == nextCnt)
            N /= 3;
        else if (N % 2 == 0 && dp[N / 2] == nextCnt)
            N /= 2;

        else
            N--;
        nextCnt--;
    }
}

 

'문제 풀이 > 백준' 카테고리의 다른 글

BOJ 1726번: 로봇  (0) 2023.03.23
BOJ 23309번: 철도 공사  (0) 2023.03.22
BOJ 2623번: 음악프로그램  (0) 2023.03.21
BOJ 1584번: 게임  (0) 2023.03.18
BOJ 2636번: 치즈  (0) 2023.03.18
profile

danbibibi

@danbibibi

꿈을 꾸는 시간은 멈춰 있는 것이 아냐 두려워하지 마 멈추지 마 푸른 꿈속으로