만드는 중입니다

아직 만드는 중이라 바뀔 수 있습니다

포크

시간 제한0.15초메모리 제한1024 MB

요약
확률 P로 두 셸 중 하나에 키 입력이 무작위로 배분될 때, 고정된 N글자 문자열을 두 셸에 완성하는 키 입력 횟수의 기댓값 최솟값을 구합니다.
난이도

어려움10점 중 8점

유형
동적 계획법, 확률
정답자
아직 제출이 없습니다

문제

루카는 파이썬 셸을 열고 os.fork()를 입력했고, 그 결과 두 번째 셸이 생겼다. 이후 루카가 키를 누를 때마다 그 키 입력은 두 셸 중 하나로 무작위로 간다. 각 셸에는 터미널에 표시되는 입력 문자열이 있고, 그 셸로 간 키 입력에 따라 문자열이 바뀐다. 루카는 터미널을 보고 있어서, 키를 누를 때 어느 셸의 입력 문자열이 바뀌었는지 안다.

그의 키보드에는 서로 다른 문자가 적힌 NN개의 키와 Backspace 키가 있다. 문자 키 입력이 셸로 가면 그 문자가 입력 문자열 끝에 붙는다. Backspace 입력이 셸로 가면 입력 문자열의 마지막 문자가 지워진다. 입력 문자열이 비어 있으면 아무 일도 일어나지 않지만, 루카는 Backspace가 그 셸로 갔다는 것을 여전히 본다. 각 키 입력은 확률 PP로 왼쪽 셸, 확률 1−P1 - P로 오른쪽 셸에 간다.

루카는 서로 다른 NN개 문자로 이루어진 고정 문자열 a1a2⋯aNa_1 a_2 \cdots a_N을 두 셸에 모두 입력하려고 한다. 이미 왼쪽 셸에 올바른 문자 LL개를, 오른쪽 셸에 RR개를 입력했다. 따라서 두 셸의 문자열은 각각 a1a2⋯aLa_1 a_2 \cdots a_L, a1a2⋯aRa_1 a_2 \cdots a_R이다.

예를 들어 P=0.3P = 0.3, N=2N = 2(문자열은 ab일 수 있다), L=0L = 0, R=1R = 1인 경우를 생각하자. 가능한 사건 순서는 다음과 같다.

단계키방향왼쪽 셸오른쪽 셸
0a
1b오른쪽ab
2a오른쪽aba
3a왼쪽aaba
4b오른쪽aabab
5Backspace오른쪽aaba
6Backspace왼쪽aba
7Backspace왼쪽aba
8Backspace오른쪽ab
9a왼쪽aab
10b오른쪽aabb
11b왼쪽ababb
12Backspace오른쪽abab

이 경우 두 셸에 ab를 입력하는 데 키 입력을 12번 했다.

잘못된 문자는 두 셸 중 하나에 들어간 문자 가운데, 전체 문자열을 두 셸에 모두 입력하기 전에 반드시 지워야 하는 문자이다. 그런 문자만 잘못된 문자로 본다.

루카는 두 셸 중 적어도 한 곳에 잘못된 문자가 있을 때만 Backspace를 누르기로 했다. 또한 항상 잘못된 문자를 만드는 키는 누르지 않기로 했다. 루카는 키 입력 횟수의 기댓값이 가장 작은 전략을 알고 싶어 한다.

이 문제를 해결하는 프로그램 fork.cpp를 작성하라.

입력

표준 입력의 첫 번째이자 유일한 줄에 PP, NN, LL, RR이 주어진다.

출력

표준 출력의 첫 번째이자 유일한 줄에 답을 출력한다. 답은 소수점 이하 12자리 이상의 정밀도로 출력한다. 다음과 같이 출력할 수 있다.

std::cout << std::setprecision(12) << ans << std::endl;

제한

0≤L,R≤N≤2×1070 \le L, R \le N \le 2 \times 10^7

0.1≤P≤0.90.1 \le P \le 0.9

예제1

  1. 예제 1

    입력
    0.3 2 0 1
    
    예상 출력
    16.7142857142857