𝘚𝘭𝘰𝘸 𝘣𝘢𝘡 𝘴𝘡𝘦𝘒π˜₯𝘺

[λ°±μ€€] 1463번: 1둜 λ§Œλ“€κΈ° - C++ λ³Έλ¬Έ

μ½”λ”©ν…ŒμŠ€νŠΈ μ€€λΉ„/λ°±μ€€

[λ°±μ€€] 1463번: 1둜 λ§Œλ“€κΈ° - C++

.23 2021. 7. 10. 16:05
문제

μ •μˆ˜ X에 μ‚¬μš©ν•  수 μžˆλŠ” 연산은 λ‹€μŒκ³Ό 같이 μ„Έ 가지 이닀.

  1. Xκ°€ 3으둜 λ‚˜λˆ„μ–΄ 떨어지면, 3으둜 λ‚˜λˆˆλ‹€.
  2. Xκ°€ 2둜 λ‚˜λˆ„μ–΄ 떨어지면, 2둜 λ‚˜λˆˆλ‹€.
  3. 1을 λΊ€λ‹€.

μ •μˆ˜ N이 μ£Όμ–΄μ‘Œμ„ λ•Œ, μœ„와 같은 μ—°μ‚° μ„Έ 개λ₯Ό 적절히 μ‚¬μš©ν•΄μ„œ 1을 λ§Œλ“€λ €κ³  ν•œλ‹€. 연산을 μ‚¬μš©ν•˜λŠ” 횟수의 μ΅œμ†Ÿκ°’μ„ 좜λ ₯ν•˜μ‹œμ˜€.

 

μž…λ ₯

첫째 쀄에 1보닀 ν¬κ±°λ‚˜ κ°™κ³ , 106보닀 μž‘κ±°λ‚˜ 같은 μ •μˆ˜ N이 주어진닀.

 

좜λ ₯

첫째 쀄에 연산을 ν•˜λŠ” 횟수의 μ΅œμ†Ÿκ°’μ„ 좜λ ₯ν•œλ‹€.


DPλ₯Ό μ΄μš©ν•˜μ—¬ ν’€ 수 μžˆλŠ” 문제.

 

1. N이 3으둜 λ‚˜λˆ„μ–΄ 떨어지면, 3으둜 λ‚˜λˆˆλ‹€ ➑️ D[N] = D[N/3] + 1

2. N이 2둜 λ‚˜λˆ„μ–΄ 떨어지면, 2둜 λ‚˜λˆˆλ‹€ ➑️ D[N] = D[N/2] + 1

3. 1을 λΊ€λ‹€ ➑️ D[N] = D[N - 1] + 1

 

κ·ΈλŸ¬λ‚˜ μ—¬κΈ°μ„œ 주어진 κ·œμΉ™λŒ€λ‘œ 풀닀보면 틀릴 수 있기 λ•Œλ¬Έμ— ν•œλ²ˆ 더 생각을 ν•΄μ€˜μ•Ό ν•œλ‹€.

10의 경우, λ‚˜λˆ  λ–¨μ–΄μ§€λŠ” λŒ€λ‘œ ν’€λ©΄ 10->5->4->2->1 둜 4κ°€ 좜λ ₯될 수 μžˆμ§€λ§Œ, 닡은 10->9->3->1 둜 3이닀.

 

10κ³Ό 같은 경우λ₯Ό μƒκ°ν•΄μ„œ 1을 λ¨Όμ € λΉΌμ€€ λ’€ μ—°μ‚°ν•˜λŠ” κ²½μš°κ°€ 더 μž‘μ€μ§€, μ›λž˜ κ°’μ—μ„œ 연산을 ν•΄μ£ΌλŠ” κ²½μš°κ°€ 더 μž‘μ€μ§€ 비ꡐλ₯Ό ν•˜λ©° ν’€μ–΄μ€˜μ•Όν•œλ‹€.

문제λ₯Ό ν’€ λ•Œ 아직 bottom-up 방식을 κ³΅λΆ€ν•˜μ§€ μ•Šμ•˜μ„ λ•Œμ—¬μ„œ, top-down λ°©μ‹μœΌλ‘œ ν’€μ—ˆλ‹€.

 

μ½”λ“œ
#include <cstdio>
#include <vector>
#define MAX 1000001

using namespace std;

vector<int> memo(MAX, -1);
int DP(int num);

int main(void) {
    int num;
    scanf("%d", &num);
    printf("%d\n", DP(num));
    return 0;
}

int DP(int num) {
    if(num == 1) return 0;
    if(memo[num] != -1) {
        return memo[num];
    }

    memo[num] = DP(num - 1) + 1;

    if(num % 3 == 0) {
        memo[num] = (DP(num / 3) + 1) < memo[num] ? DP(num / 3) + 1 : memo[num];
    }
    if (num % 2 == 0) {
        memo[num] = (DP(num / 2) + 1) < memo[num] ? DP(num / 2) + 1 : memo[num];
    }
    return memo[num];
}

 

+) 2022.02.10 μΆ”κ°€

bottom-up λ°©μ‹μœΌλ‘œλ„ ν’€μ–΄λ³΄μ•˜λ‹€. 보면 μ•Œκ² μ§€λ§Œ 접근방법도, μˆ˜μ‹λ„ λ™μΌν•˜κ²Œ ν’€μ–΄μ£Όλ˜, μž¬κ·€μ—μ„œ 반볡문으둜만 λ°”κΏ”μ£Όλ©΄ λœλ‹€.

μ½”λ“œ(2)
#include <cstdio>
#define MAX 1000001

int DP(int num);
int min(int a, int b) {
    return a < b ? a : b;
}

int main(void) {
    int n;
    scanf("%d", &n);

    printf("%d\n", DP(n));
    return 0;
}

int DP(int num) {
    int memo[MAX];

    for(int i = 2; i <= num; i++) {
        memo[i] = memo[i - 1] + 1;

        if(i % 3 == 0) {
            memo[i] = min(memo[i], memo[i / 3] + 1);
        }
        if(i % 2 == 0) {
            memo[i] = min(memo[i], memo[i / 2] + 1);
        }
    }

    return memo[num];
}
Comments