알고리즘 문제/SWEA

[SWEA - Java] 1266. 소수 완제품 확률

건복치 2021. 10. 27. 03:37
반응형

문제

https://swexpertacademy.com/main/code/problem/problemDetail.do?contestProbId=AV18Sx36IwACFAZN 

설명

주어진 시간은 90분이며, 각 가구 장인은 5분 안에 최대 1개의 완제품을 만들 수 있다고 가정

 

5분에 성공하면 최대 1개 / 실패하면 0개

  • 90분간 모두 성공하면 → 18개
  • 90분간 모두 실패하면 → 0개

 

5분 10분 15분



...




    90분
1 2 3 16 17 18
Fail : 0
or
Success : 1
         

18개 중 소수는 2, 3, 5, 7, 11, 13, 17

→ 2개, 3개, ... , 17개 해당 소수 개의 개수만큼 완제품이 나올 확률을 다 더한 값

 장인이 만든 완제품의 수가 소수일 확률

 

 

A장인, B장인 두 명이니까

A장인이 만든 완제품의 수가 소수일 확률 + B장인이 만든 완제품의 수가 소수일 확률 = 정답

 

A장인을 예로 들어보자(B도 똑같은 방식으로 구하면 됨)

skillOfMasterA = A장인이 5분 안에 완제품을 만들 확률 = 80

skillOfMasterA = 100/80 = 5/4

성공할 확률 5/4 - 실패할 확률 5/1

 

A장인이 소수 2, 2개의 완제품을 만들 확률?

18C2 * (5/4)^2 * (5/1)^16 = 18개 중 2개 만큼만 완제품으로 만들 확률

 

  • 18C2 : 18개 중 소수2, 2개만큼을 뽑는 경우의 수 
  • (5/4)^2 : 각 경우에서 2개 만드는데 성공할 확률
  • (5/1)^16 : 각 경우에서 2개 만드는데 실패할 확률(18-2=16)

18개중 소수 N만큼 뽑는 경우의 수  * 각 경우에서 N개 만드는 데 성공할 확률 * 각 경우에서 N개 만드는데 실패할 확률

 

 

2개 만큼 완제품으로 만들 확률 + 3개 확률 + 5개 확률 +... + 17개 확률 = A가 소수개 완제품을 만들 확률

 

→ 2, 3, 5, 7, 11, 13, 17에서의 완제품 만들 확률을 다 뽑고 이를 합하면 됨

ex)

18C2 * (5/4)^2 * (5/1)^16

+

18C3 * (5/4)^3 * (5/1)^15

+

18C5 * (5/4)^5 * (5/1)^13

+

...

+

18C17 * (5/4)^17 * (5/1)^1

 

문제에서 요구하는 완제품이 최소 한 명이라도 소수일 확률?

1 - (1-A) * (1-B) = A, B장인에게서 소수 개 완제품이 하나라도 나올 확률 =  완제품이 최소 한 명이라도 소수일 확률

 

  • (1-A) : 전체 확률 - A장인이 소수 개 완제품을 만들 확률 = A장인이 완제품을 단 하나라도 소수 개수로 만들지 못할 확률
  • (1-B) : 위와 마찬가지
  • (1-A) * (1-B) : A, B 장인에게서 소수가 한 번도 나오지 않을 확률

전체 코드

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.StringTokenizer;

class Solution {
	static int[] primeNumbers = {2, 3, 5, 7, 11, 13, 17};

	public static void main(String args[]) throws IOException {
		BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
		StringBuilder sb = new StringBuilder();
		StringTokenizer st;

		int T = Integer.parseInt(br.readLine());

		for(int test_case = 1; test_case <= T; test_case++) {
			st = new StringTokenizer(br.readLine());

			// 5분 안에 완제품을 만들 확률
			double skillA = Double.parseDouble(st.nextToken()) / 100;
			double skillB = Double.parseDouble(st.nextToken()) / 100;

			double A = 0, B = 0;

			for(int i = 0; i < primeNumbers.length; i++) {
				// 18개중 소수 N만큼 뽑는 경우의 수  * 각 경우에서 N개 만드는데 성공할 확률 * 각 경우에서 N개 만드는데 실패할 확률
				A += combination(18, primeNumbers[i]) * Math.pow(skillA, primeNumbers[i]) * Math.pow(1-skillA, 18-primeNumbers[i]);
				B += combination(18, primeNumbers[i]) * Math.pow(skillB, primeNumbers[i]) * Math.pow(1-skillB, 18-primeNumbers[i]);
			}
			
			//double result = 1 - (1 - A) * (1 - B);
			double result =  A + B - (A * B);

			sb.append("#" + test_case + " " + String.format("%.6f", result) + "\n");			
		}

		System.out.println(sb.toString());
	}

	// 조합의 수 구하기 - nCr
	public static int combination(int n, int r) {
		if(n == r || r == 0) 
			return 1; 
		else 
			return combination(n - 1, r - 1) + combination(n - 1, r); 
	}

}
반응형