본문 바로가기

백준 문제 풀이

백준 22353번 헤이카카오 (C++)

728x90

https://www.acmicpc.net/problem/22353

 

22353번: 헤이카카오

첫 번째 줄에는 세 개의 정수 $a, d, k$가 공백으로 구분되어 주어진다. $(1 \leq a, d, k \leq 100)$ 이는 끝말잇기 한 판에 $a$분이 걸리며 집중을 시작한 이하가 처음에 끝말잇기에서 이길 확률이 $d$%이

www.acmicpc.net

 

 확률은 가장 못했던 것이기도하고 지금도 잘 못한다. 실랜디를 하면서 여러가지 분류를 해 볼수 있어서 좋은 것 같다. 우선 기댓값이란 "각 사건이 일어났을 때의 이득과 그 사건이 벌어질 확률을 곱하여 더한 것" 이다.

즉 여기서 구할 기댓값은 "시간" 이다.

 

즉 예제인 1 50 50 을 수식을 만들어보면 다음과 같다.

 

1번째 게임에서 승리 : 첫번째 게임에서 이길 확률 50%

2번째 게임에서 승리 : 첫번째 게임에서 질 확률 50% * 두번 째 게임에서 이길 확률 50 + 50 * 1 / 2 = 75 %

3번째 게임에서 승리 : 첫번째 게임에서 질 확률 50% * 두번 째 게임에서 질 확률 + 세번째 게임에서 이길 확률 

 

이다. 그리고 각 퍼센트에 시간을 곱하고 더하면 된다.

 

코드를 작성하기 위해 일반화시켜보자.

 

정답 += 지금까지 질 확률 * 이번에 이길 확률 * 시간

지금까지 질 확률 *= 지금까지 질 확률 * 이번에도 질 확률

이번엔 이길 확률 = 이전에 이길확률 * k * 0.01

 

갱신해야할 값은 지금까지 질 확률과 이번에는 이길 확률이다. 

 

#include<iostream>

using namespace std;

int main() {
    ios_base::sync_with_stdio(false);
    cin.tie(NULL);
    cout.tie(NULL);

    int a, d, k;

    cin >> a >> d >> k;

    double per = 1.0;
    double win_per = d * 0.01;
    double sum = 0.0;
    double idx = 1.0;
    while (true) {
        sum += idx * a * per * win_per;
        per *= (1.0 - win_per);
        win_per += win_per * k * 0.01;
        idx++;
        if (win_per >= 1) {
            sum += idx * per * a;
            break;
        }
    }

    cout << fixed;
    cout.precision(8);
    cout << sum << '\n';

    return 0;
}