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