Stay Hungry Stay Foolish

BOJ 코딩테스트/Silver

BOJ 9095번 : 1, 2, 3 더하기 (C++/Silver 3)

dev스카이 2022. 9. 23. 06:57
 

9095번: 1, 2, 3 더하기

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

www.acmicpc.net

문제

정수 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의 합으로 나타내는 방법의 수를 출력한다.


예제 입력

3
4
7
10

예제 출력

7
44
274

풀이

▶ DP 알고리즘 사용 : Top-Down과 Bottom-Up 방식 중 Bottom-Up 반복문을 사용

 

먼저 문제의 규칙을 보자.

n = 1 n = 2 n = 3 n = 4 n = 5 ...
1 2
1+1
3
2+1
1+2
1+1+1
3+1
2+2
2+1+1
1+3
1+2+1
1+1+2
1+1+1+1
3+2
3+1+1
2+3
2+2+1
2+1+2
2+1+1+1
1+3+1
1+1+3
1+2+2
1+2+1+1
1+1+2+1
1+1+1+2
1+1+1+1+1
...
1개 2개 4개 7개 13개 ...

 

n = 4일때, 합의 총 개수가 7개인데 이는 앞의 1개 + 2개 + 4개(n = 1, 2, 3)를 더한 합과 같다. 그 다음 n = 5일 때, 합의 총 개수가 13개인데 이 또한 앞의 2개+4개+7개(n = 2, 3, 4)를 더한 합과 같다. 이처럼 n=4일 때부터 규칙이 생긴다. 

따라서 n이 1부터 3까지는 따로 값을 저장해두고, 4부터는 반복문을 통해서 구현한다.

Solution

#include <iostream>
using namespace std;

int T, n, s[12];
int DP(int n){
    s[1] = 1; 
    s[2] = 2;
    s[3] = 4;
    for(int i = 4; i <= n; i++)
        s[i] = s[i - 1] + s[i - 2] + s[i - 3];
    return s[n];
}
int main() {
    cin >> T;
    for(int i=0; i<T; i++){
        cin >> n;
        cout << DP(n) << '\n';
    }
    return 0;
}