T'SPACE

다채로운 에디터들의 이야기

컴퓨터공학/알고리즘

[백준,C++] 1463번: 1로 만들기

Tonny Kang 2024. 2. 26. 08:10
반응형

 

반응형

문제

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

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

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

728x90

입력

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

SMALL

출력

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

예제 입력 1 복사

2

예제 출력 1 복사

1

예제 입력 2 복사

10

예제 출력 2 복사

3

힌트

10의 경우에 10 → 9 → 3 → 1 로 3번 만에 만들 수 있다.

 

진짜 다양한 방법으로 생각해봤는데

우선 3으로 나누는게 무조건 이득이라 생각해

3으로 나눠지게 만든 후 2로 나누고

 

밑에서 시작해서 1 더하고 2 더하고 해봤는데

 

다 답을 못 구했다.. 여기서 정석은

 

Dynamic Programming 다이나믹(동적) 프로그래밍

이였다

 

전체적인 문제를 작은 문제로 나눠서 푸는 것이다

여기서 divide and conquer이랑 비슷하다고 느낄 수 있는데

요거는 전에 작은 문제의 결과 값을 활용해 

계산을 하는 것이다

 

가장 대중적인 예로 피보나치를 구할 때

전의 값들을 구해둬 더하는 것이다

 

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

int main()
{
    int N;
    scanf("%d",&N);
    int counts[10000001];

    counts[0] = 0;
    counts[1] = 0;
    counts[2] = 1;
    counts[3] = 1;

    for(int i=4; i<=N; i++)
    {
        counts[i] = counts[i-1] + 1;
        if(i%2==0) counts[i] = min(counts[i], counts[i/2]+1);
        if(i%3==0) counts[i] = min(counts[i],counts[i/3]+1);
    }
    printf("%d\n",counts[N]);
    return 0;
}

 

 그래서 1 부터 시작해 

i번째 값

counts[i]의 값은 

counts[i-1]에서 1 더한 값이랑 counts[i/3]에 3을 곱한, counts[i/2]에 2를 곱한 값들 중에 최소값이다

 

그렇게 경우의 수를 구해두고

N을 출력하면 된다

 

<[백준,c++] 1107: 리모컨>

https://tonnykang.tistory.com/118

 

[백준,C++] 1107 : 리모컨

문제 수빈이는 TV를 보고 있다. 수빈이는 채널을 돌리려고 했지만, 버튼을 너무 세게 누르는 바람에, 일부 숫자 버튼이 고장났다. 리모컨에는 버튼이 0부터 9까지 숫자, +와 -가 있다. +를 누르면

tonnykang.tistory.com

 

반응형

'컴퓨터공학 > 알고리즘' 카테고리의 다른 글

C++, C 언어 알고리즘 표준 입출력  (58) 2024.03.01
[백준/C++] 1541: 잃어버린 괄호  (55) 2024.02.27
[백준,C++] 1107 : 리모컨  (49) 2024.02.20
[백준,C++] 1074번 : Z  (50) 2024.02.19
[백준/C++] 1654 : 랜선 자르기  (48) 2024.02.14