문제
정수 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의 합으로 나타내는 방법의 수를 출력한다.
해결 방법
정수 4를 1, 2, 3의 합으로 나타낼 수 있는 모든 경우의 수를
1로 시작하는 경우
2로 시작하는 경우
3으로 시작하는 경우
이렇게 순서대로 나열해보면
아래와 같다.
여기서 규칙을 발견할 수 있는데
1로 시작하는 경우는 1 + (3을 1, 2, 3의 합으로 나타낸 모든 경우)와 같고
2로 시작하는 경우는 2 + (2을 1, 2, 3의 합으로 나타낸 모든 경우)와 같고
3으로 시작하는 경우는 3 + (1을 1, 2, 3의 합으로 나타낸 모든 경우)와 같다는 것이다.
즉, 그림으로 나타내면 아래와 같다.
점화식으로 나타내면 이렇게 된다!
dp[n] = dp[n-3] + dp[n-2] + dp[n-1]
내 코드
1. Top-down (재귀)
// [9095] 1, 2, 3 더하기
// https://www.acmicpc.net/problem/9095
// dp(Top-down)
#include <iostream>
using namespace std;
int dp[11] { 0, 1, 2, 4, };
int go(int n)
{
if(dp[n] != 0) return dp[n];
dp[n] += go(n-3);
dp[n] += go(n-2);
dp[n] += go(n-1);
return dp[n];
}
int main(void)
{
int t, n;
cin >> t;
while(t--) {
cin >> n;
cout << go(n) << '\n';
}
}
2. Bottop-up (반복문)
// [9095] 1, 2, 3 더하기
// https://www.acmicpc.net/problem/9095
// dp(Bottom-up)
#include <iostream>
using namespace std;
int main(void)
{
int t, n; // the number of test cases
int arr[12] = { 0, 1, 2, 4, };
cin >> t;
for (int i = 0; i < t; i++)
{
cin >> n;
for (int j = 4; j <= n; j++) {
arr[j] = arr[j - 1] + arr[j - 2] + arr[j - 3];
}
cout << arr[n] << endl;
}
}
반응형
'Baekjoon > DP' 카테고리의 다른 글
[15990] 1, 2, 3 더하기 5(C++) (0) | 2021.07.14 |
---|---|
[16194] 카드 구매하기2 (0) | 2021.07.13 |
[1309] 동물원 (0) | 2020.08.15 |
[1149] RGB거리 (0) | 2020.06.21 |
[2352] 반도체 설계(C++) (0) | 2020.05.30 |