728x90
문제
https://www.acmicpc.net/problem/28075
3줄 요약
- 이 문제는 N일 동안 A와 B 두 곳을 방문하는 모든 경우의 수를 구하는 문제로, 중복순열(Permutation with Repetition)을 활용하여 해결할 수 있습니다.
- 중복순열은 순서를 고려하며, 같은 요소를 여러 번 선택할 수 있는 경우의 수를 의미합니다.
- 이 문제에서는 각 일자마다 A 또는 B 중 하나를 선택하며, 이전에 선택한 장소와 같은 장소를 다시 선택할 수 있습니다.
- 재귀 함수 recursiveSearch를 사용하여 중복순열을 생성하며, 각 경우에서 얻을 수 있는 진척도의 합을 계산합니다.
- 재귀 함수의 매개변수로는 현재 방문 중인 일자(day), 이전에 방문한 장소(prev), 현재까지 누적된 진척도(progress)가 사용됩니다.
- 기저 조건으로 N일 동안 방문이 완료되었을 때, 누적된 진척도 합이 M 이상인 경우 경우의 수를 증가시킵니다.
- 최종적으로 모든 중복순열을 탐색한 후, 조건을 만족하는 경우의 수를 출력합니다.
중복순열을 활용하여 모든 경우를 탐색함으로써 문제에서 요구하는 진척도 합이 M 이상이 되는 경우의 수를 정확히 계산할 수 있습니다.
코드
// package boj28075;
import java.io.*;
import java.util.*;
public class Main {
public static void main(String[] args) throws Exception {
// System.setIn(new FileInputStream("src/input.txt"));
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
// N과 M 입력받기
StringTokenizer st = new StringTokenizer(br.readLine());
N = Integer.parseInt(st.nextToken()); // 일수
M = Integer.parseInt(st.nextToken()); // 목표 진척도
// A 장소의 진척도 입력받기
A = new int[3];
st = new StringTokenizer(br.readLine());
for (int i = 0; i < 3; i++) {
A[i] = Integer.parseInt(st.nextToken());
}
// B 장소의 진척도 입력받기
B = new int[3];
st = new StringTokenizer(br.readLine());
for (int i = 0; i < 3; i++) {
B[i] = Integer.parseInt(st.nextToken());
}
br.close();
// 재귀를 활용한 경우의 수 계산
recursiveSearch(0, -1, 0);
// 결과 출력
BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.out));
bw.write(Integer.toString(count));
bw.flush();
bw.close();
}
public static int N; // 일수
public static int M; // 목표 진척도
public static int[] A; // A 장소의 진척도
public static int[] B; // B 장소의 진척도
public static int count = 0; // 경우의 수
public static void recursiveSearch(int day, int prev, int progress) {
// 기저 조건: N일 동안 방문한 경우
if (day == N) {
// 진척도 합이 M 이상인 경우 경우의 수 증가
if (progress >= M) {
count++;
}
return;
}
// 각 장소에 대해 재귀 호출
for (int i = 0; i < 3; i++) {
// 이전에 방문한 장소와 동일한 경우
if (i == prev) {
// A 장소 방문 (진척도 절반)
recursiveSearch(day + 1, i, progress + A[i] / 2);
// B 장소 방문 (진척도 절반)
recursiveSearch(day + 1, i, progress + B[i] / 2);
} else {
// A 장소 방문 (진척도 전체)
recursiveSearch(day + 1, i, progress + A[i]);
// B 장소 방문 (진척도 전체)
recursiveSearch(day + 1, i, progress + B[i]);
}
}
}
}
'Problem_Solving' 카테고리의 다른 글
백준(BOJ) 9012 : 괄호 (실버4) / 자바(Java) 풀이 (0) | 2024.05.14 |
---|---|
백준(BOJ) 6603 : 로또 (실버3) / 자바(Java) 풀이 (0) | 2024.05.12 |
백준(BOJ) 15658 : 연산자 끼워넣기 (2) (실버2) / 자바(Java) 풀이 (0) | 2024.05.11 |
백준(BOJ) 10819 : 차이를 최대로 (실버2) / 자바(Java) 풀이 (0) | 2024.05.10 |
백준(BOJ) 1182 : 부분수열의 합 (실버2) / 자바(Java) 풀이 (0) | 2024.05.10 |