문제
정수 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을 모두 더하는 경우의 수를 완전 탐색으로 찾아보자.
찾은 후 그 결과가 현재 구하고자 하는 N의 값과 일치한다면 그 경우는 성공적인 것이며,
이외의 경우는 추가 연산이 필요하거나 실패한 경우이다.
여기서 실패한 경우란, 현재 재귀 함수로 만든 합의 결과(함수의 상태)가 N보다 클 때이며
성공한 경우는 위 합의 결과가 N과 같은 경우이다.
=> 그래서 우리는 N과 큰 경우, N과 같은 상태 인 2가지 탈출조건을 만들 수 있다.
각가의 경우를 하나의 성공/실패의 경우의 수라고 볼 수 있다.
이 문제는 전체 경우의 수를 구하는 문제이므로 성공 시에만 전체 경우의 수에 +1 하도록
반환한다면 그 결과를 구할 수 있다.
풀이
import java.io.*;
public class Main {
public static int countSum(int n, int cur) {
if(cur >= n) {
if(cur == n) return 1;
return 0;
}
int result = 0;
for(int i = 1; i <= 3; i++)
result += countSum(n, cur + i);
return result;
}
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
int n = Integer.parseInt(br.readLine());
while(n-- != 0)
System.out.println(countSum(Integer.parseInt(br.readLine()), 0));
}
}
** 아직 확실히 이해 가지 않는 부분은
왜? for 문을 3번만 도는 것인가에 대해서이다 . .
1, 2, 3 <- 이렇게 세가지 경우의 수가 주어지기 때문인걸까 ? . .
더 고민해봐야겠다 . .
© 참고
https://www.acmicpc.net/problem/9095
'Study > algorithm' 카테고리의 다른 글
[백준/Java] 11723 집합 (feat. 비트마스크) (0) | 2021.10.12 |
---|---|
[백준/Java/DP] 9095 1, 2, 3 더하기 (0) | 2021.10.06 |
[백준/Java/DP] 11726 2xn 타일링 (feat. 다이나믹 프로그래밍) (0) | 2021.10.06 |
[백준/Java] 9613 GCD 합 (feat. 유클리드 호제법) (0) | 2021.10.06 |
[백준/Java] 1676 팩토리얼 0의 개수* (0) | 2021.10.06 |