본문으로 바로가기

[DP] 9095번 1,2,3 더하기

category Algorithm/BOJ 문제풀이 2018. 11. 7. 17:04
9095_1,2,3 더하기

9095번 1, 2, 3 더하기

 

https://www.acmicpc.net/problem/9095


 

문제

정수 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

 

해결방법

본 문제는 원래 DFS 탐색을 통해 해결했었다.

이번에는 DP를 이용하여 문제를 풀었다.

d[n]은 n을 1,2,3의 합으로 나타낼 수 있는 방법의 수 이다.

d[n]의 마지막에는 1,2,3 세 숫자가 나올 수 있다.

따라서 순환식은 d[n] = d[n-1] + d[n-2] + d[n-3] 으로 나타낼 수 있다.

 

 

 

소스코드

1️⃣ Top-down

#include <iostream>
#include <cstring>
#include <math.h>
#include <algorithm>
#define MAX 11
using namespace std;

int testcase,n;
int d[MAX];

/*
 
 순환식 : d[n] = d[n-1] + d[n-2] + d[n-3]
 
 */

int dp(int i){
    if(i == 1) return 1;
    if(i == 2) return 2;
    if(i == 3) return 4;
    
    if(d[i] > -1){
        return d[i];
    }else{
        d[i] = dp(i-1) + dp(i-2) + dp(i-3);
        return d[i];
    }
}

int main(int argc, const char * argv[]) {
    // cin,cout 속도향상
    ios_base::sync_with_stdio(false);
    cin.tie(NULL); cout.tie(NULL);
    
    cin >> testcase;
    
    for(int t=0; t<testcase; t++){
        cin >> n;
        
        memset(d, -1, sizeof(d));
        
        cout << dp(n) << "\n";
    }
    
    return 0;
}

 

2️⃣ Bottom-up

#include <iostream>
#include <cstring>
#include <math.h>
#include <algorithm>
#define MAX 11
using namespace std;

int testcase,n;
int d[MAX];

/*
 
 순환식 : d[n] = d[n-1] + d[n-2] + d[n-3]
 
 */

void dp(){
    d[1] = 1;
    d[2] = 2;
    d[3] = 4;
    
    for(int i=4; i<=n; i++){
        d[i] = d[i-1] + d[i-2] + d[i-3];
    }
}

int main(int argc, const char * argv[]) {
    // cin,cout 속도향상
    ios_base::sync_with_stdio(false);
    cin.tie(NULL); cout.tie(NULL);
    
    cin >> testcase;
    
    for(int t=0; t<testcase; t++){
        cin >> n;
        
        memset(d, 0, sizeof(d));
        
        dp();
        
        cout << d[n] << "\n";
    }
    
    return 0;
}

 

'Algorithm > BOJ 문제풀이' 카테고리의 다른 글

[DP] 11727번 2xn 타일링2  (0) 2018.11.07
[DP] 11726번 2xn 타일링  (0) 2018.11.07
[DP] 1463번 1로 만들기  (0) 2018.11.07
[BF] 13458번 시험 감독  (0) 2018.11.05
[BFS] 2638번 치즈  (0) 2018.11.05