조합 예제 - 5
문제 분석
단순한 조합을 이용해 색깔별 조약돌의 개수에서 K개를 뽑을 수 있는 경우의 수를 구한 후, 전체 돌에 관해 n개를 뽑는 경우의 수를 나눠도 이 문제를 해결할 수 있다.(
(aCk + bCk + cCk +...)/nCk(n = a+b+c+...))하지만 단순하게 확률식을 세워서 계산해도 풀 수 있다.
알고 있는 알고리즘에 문제를 맞추려 하지 말고 넓은 시야로 문제를 분석할 수 있어야 한다.
손으로 풀어보기
색깔별 조약돌의 개수를 배열에 저장하고, 전체 조약돌 개수를 변수에 저장한다.
예제 입력 3 기준 :
5 + 6 + 7 = 18
한 색깔의 조약돌만 뽑을 확률을 색깔별로 모두 구한다.
k = 2이므로 2번 뽑을 동안 같은 색이 나올 확률을 구하면 된다.5개의 조약돌이 있는 색깔만 뽑을 확률 :
5 / 18*4 / 176개의 조약돌이 있는 색깔만 뽑을 확률 :
6 / 18*5 / 177개의 조약돌이 있는 색깔만 뽑을 확률 :
7 / 18*6 / 17
각각의 확률을 더해 정답을 출력한다.
슈도코드
stone(색깔별 조약돌 개수 저장 리스트)
probability(색깔별 확률 저장 리스트)
m(색의 종류)
sum(전체 조약돌 개수)
for m 반복:
sum에 조약돌 개수 더하기
k(선택한 조약돌 개수)
for m 반복:
if 현재 색깔의 조약돌의 개수가 선택해야 할 개수보다 크면: # 선택한 조약돌 개수(k)보다 현재 색 조약돌 개수가 적으면 모두 같은 색으로 뽑힐 확률은 0
probability[i]를 1로 저장 # 확률 초기 값
for j k만큼:
i 색깔을 모두 뽑을 확률 = i 색깔을 모두 뽑을 확률 * (현재 색깔 개수 - j) / (전체 색깔 개수 - j)
정답에 현재 색깔을 모두 뽑을 확률(probability[i])을 더하기
정답 출력코드 구현 - 파이썬
m = int(input()) # 색깔 개수
stone = list(map(int, input().split())) # 색깔별 조약돌 개수
probability = [0] * 51 # 색깔별 확률
sum = 0 # 전체 조약돌 개수
for i in range(m):
sum += stone[i]
k = int(input()) # 선택한 조약돌 개수
result = 0
for i in range(m):
if stone[i] >= k: # 최소한 조약돌이 선택한 조약돌의 개수보다 크거나 같아야 뽑힐 확률이 있다.
probability[i] = 1
for j in range(k):
probability[i] *= (stone[i] - j) / (sum - j)
result += probability[i]
print(result)코드 구현 - 자바
import java.io.*;
import java.lang.reflect.Array;
import java.util.*;
public class Main {
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
int m = Integer.parseInt(br.readLine());
int[] stone = Arrays.stream(br.readLine().split(" "))
.mapToInt(Integer::parseInt)
.toArray();
double[] probability = new double[51];
int sum = 0;
for (int i = 0; i < m; i++) {
sum += stone[i];
}
int k = Integer.parseInt(br.readLine());
double result = 0;
for (int i = 0; i < m; i++) {
if (stone[i] >= k) {
probability[i] = 1;
for (int j = 0; j < k; j++) {
probability[i] *= (double) (stone[i] - j) / (sum - j);
}
result += probability[i];
}
}
System.out.println(result);
}
}Last updated