[재귀] BOJ 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의 합으로 5를 만드는 방법의 수는
5에 1, 2, 3을 빼서 0을 만드는 방법의 수와 같습니다.
위 그림에서 5를 0으로 만드는 모든 경우의 수를 보여주지는 않았지만
한 가지 파악할 수 있는 부분이 있습니다.
5를 0으로 만드는 방법의 수는 4, 3, 2를 0으로 만드는
방법의 수를 더한 것과 같다.
그리고 이 4, 3, 2는 5에서 1, 2, 3을 뺀 수와 같습니다.
바로 이 부분, 계산을 해서 나온 값들이 이전 값의 결과에 영향을 미치는 부분을 찾으면
재귀 함수의 설계는 거의 끝납니다.
여기까지 설계가 되면 도출될 수 있는 함수의 모양은 이렇습니다.
하지만, 이렇게만 하면 재귀 함수는 무한적으로 실행됩니다.
때문에 재귀가 끝나는 조건을 설정해줍니다.
1. N 이 0보다 작아진 경우 0을 리턴
2. N 이 1 보다 작거나 같은 경우 1을 리턴
여기까지 설계하면 재귀 함수가 완성됩니다.
코드
#include <iostream>
using namespace std;
int go(int n) {
if (n < 0) return 0;
if (n <= 1) return 1;
return go(n - 1) + go(n - 2) + go(n - 3);
}
int main() {
int k;
cin >> k;
while (k--) {
int n;
cin >> n;
cout << go(n) << '\n';
}
return 0;
}