포스트

BOJ9095

BaekJoon 9095 : 1, 2, 3 더하기

문제

정수 4를 1, 2, 3의 합으로 나타내는 방법은 총 7가지가 있다. 합을 나타낼 때는 수를 1개 이상 사용해야 한다.

  • 1+1+1+1
  • 1+1+2
  • 1+2+1
  • 2+1+1
  • 2+2
  • 1+3
  • 3+1 정수 n이 주어졌을 때, n을 1, 2, 3의 합으로 나타내는 방법의 수를 구하는 프로그램을 작성하시오.

입력

첫째 줄에 테스트 케이스의 개수 T가 주어진다. 각 테스트 케이스는 한 줄로 이루어져 있고, 정수 n이 주어진다. n은 양수이며 11보다 작다.

출력

각 테스트 케이스마다, n을 1, 2, 3의 합으로 나타내는 방법의 수를 출력한다.

나의 첫번째 답

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
#include <iostream>

int FindAllCases(int input) {

    // 기본 경우에는 재귀를 사용 X
    if(input == 1)
        return 1;
    else if (input == 2)
        return 2;
    else if (input == 3)
        return 4;
    else    // 그렇지 않을 때는 재귀 O
        return FindAllCases(input-3) + FindAllCases(input-2) + FindAllCases(input-1);

}

int main() {

    int T;      // 테스트 케이스의 갯수
    std::cin >> T;

    int n[T];

    for (int i = 0; i < T; i++)
    {
        std::cin >> n[i];
    }

    for (int i = 0; i < T; i++)
    {
        std::cout << FindAllCases(n[i]) << std::endl;
    }
    
    return 0;
}

천천히 머릿속으로 몇 번 세어보니, 재귀로 풀면 될 것 같았고, 그래서 재귀로 풀었더니 생각보다 금방 풀렸다.

그러나 이렇게하면, 매번 처음부터 다시 계산해야 한다. 구하고자 하는 숫자가 작으면 별 문제 없겠지만, 숫자가 커지면 커질 수록, 그리고 여러 번 반복해서 호출할수록 비효율적이다.

이를 개선해서, 배열 한 곳에 저장하는 방식을 추가해서 코드를 개선해보았다.

두번째 답

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
#include <iostream>
#include <algorithm>    // max_element() 함수를 쓰기 위해 include

int findAllCases(int input, int* arr) {

    // n이 3보다 큰 경우에만 계산 및 저장
    for (int i = 4; i <= input; i++) {
        arr[i] = arr[i-1] + arr[i-2] + arr[i-3];
    }

    return arr[input];   
}

int main() {

    int T;      // 테스트 케이스의 갯수
    std::cin >> T;

    int n[T];

    for (int i = 0; i < T; i++)
    {
        std::cin >> n[i];
    }

    int max = *std::max_element(n, n+T);
    int store[max] = {0};   // 입력값 중 최대값만큼만 배열을 만들고

    // 기본 경우 초기화
    store[1] = 1; // 1을 만드는 방법은 1가지
    store[2] = 2; // 2를 만드는 방법은 2가지
    store[3] = 4; // 3을 만드는 방법은 1+1+1, 1+2, 2+1, 3 총 4가지

    for (int i = 0; i < T; i++)
    {
        std::cout << findAllCases(n[i], store) << std::endl;
    }
    
    return 0;
}
이 기사는 저작권자의 CC BY 4.0 라이센스를 따릅니다.