C. Need for Pink Slips
问题:一个游戏,给出 C , M , P C,M,P C,M,P三个事件,每个事件的概率是 c , m , p c,m,p c,m,p,当出现事件 P P P的时候,游戏结束。在每一轮游戏过程中 c , m , p c,m,p c,m,p都会根据规则发生变化。问游戏进行多少轮的期望。
规则:给定一个小数 v v v。
-
( c , m , p ) = ( 0.2 , 0.1 , 0.7 ) (c,m,p)=(0.2,0.1,0.7) (c,m,p)=(0.2,0.1,0.7), v = 0.1 v=0.1 v=0.1, 在发生事件C后,因为 c > v c>v c>v,所以 c = c − v , m = v / 2 + m , p = v / 2 + p c=c-v,m=v/2+m, p = v/2+p c=c−v,m=v/2+m,p=v/2+p, ( c , m , p ) = ( 0.1 , 0.15 , 0.75 ) (c,m,p)=(0.1,0.15,0.75) (c,m,p)=(0.1,0.15,0.75).
-
( c , m , p ) = ( 0.1 , 0.2 , 0.7 ) (c,m,p)=(0.1,0.2,0.7) (c,m,p)=(0.1,0.2,0.7), v = 0.2 v=0.2 v=0.2, 在发生事件C后,因为 c ≤ v c\le v c≤v,所以 c = 0 , m = c / 2 + m , p = c / 2 + p c=0,m=c/2+m, p = c/2+p c=0,m=c/2+m,p=c/2+p, ( c , m , p ) = ( 0 , 0.25 , 0.75 ) (c,m,p)=(0,0.25,0.75) (c,m,p)=(0,0.25,0.75).
-
( c , m , p ) = ( 0.2 , 0 , 0.8 ) (c,m,p)=(0.2,0,0.8) (c,m,p)=(0.2,0,0.8), v = 0.1 v=0.1 v=0.1, 在发生事件C后,因为 c > v c>v c>v,但是 m = 0 m=0 m=0,所以 c = c − v , m = , p = v + p c=c-v,m=, p = v+p c=c−v,m=,p=v+p, ( c , m , p ) = ( 0.1 , 0 , 0.9 ) (c,m,p)=(0.1,0,0.9) (c,m,p)=(0.1,0,0.9)
-
( c , m , p ) = ( 0.1 , 0 , 0.9 ) (c,m,p)=(0.1,0,0.9) (c,m,p)=(0.1,0,0.9), v = 0.2 v=0.2 v=0.2, 在发生事件C后,因为 c ≤ v c\le v c≤v,但是 m = 0 m=0 m=0,所以 c = 0 , m = 0 , p = c + p c=0,m=0, p = c+p c=0,m=0,p=c+p, ( c , m , p ) = ( 0 , 0 , 1 ) (c,m,p)=(0,0,1) (c,m,p)=(0,0,1)
解答:期望=轮数*概率,根据规则, d f s dfs dfs每一种情况,都加起来就是答案,注意设置esp。
#include <bits/stdc++.h>
using namespace std;
// #define double long double
typedef long long ll;
const int N = 1e4+10;
const int mod = 1e9+7;
const double esp = 1e-12;
double s[10], v, ans = 0;
double i = 1;
//s数组存放c,m,p。ans是答案。
void dfs(double val) {
//val表示出现当前情况的概率。
if(val == 0 || val*s[3] < esp) return;
else {
//val*s[3]表示下一轮就是事件p发生,能对期望产生val*s[3]*i的贡献。
ans += val*s[3]*i;
}
i += 1;
double a = s[1], b = s[2], c = s[3];
double tmp = val*a;
if(a > 0) {
//根据规则来计算下一轮c,m,p的值。
if(a <= v) {
s[1] = 0;
if(s[2] < esp) s[3] = a + s[3];
else s[2] = a/2 + s[2], s[3] = a/2 + s[3];
dfs(val*a);
s[1] = a, s[2] = b, s[3] = c;//回溯。
}
else {
s[1] = a-v;
if(s[2] < esp) s[3] += v;
else s[2] = v/2 + s[2], s[3] = v/2 + s[3];
dfs(val*a);
s[1] = a, s[2] = b, s[3] = c;
}
}
if(b > 0) {
tmp = val * b;
if(b <= v) {
s[2] = 0;
if(s[1] < esp) s[3] += b;
else s[1] = b/2+s[1] , s[3] = b/2 + s[3];
dfs(val*b);
s[1] = a, s[2] = b, s[3] = c;
}
else {
s[2] = b-v;
if(s[1] < esp) s[3] += v;
else s[1] = v/2+s[1], s[3] = v/2 + s[3];
dfs(val*b);
s[1] = a, s[2] = b, s[3] = c;
}
}
i -= 1;
}
int main() {
#ifndef ONLINE_JUDGE
freopen("in.txt", "r", stdin);
freopen("out.txt", "w", stdout);
#endif
int t;
cin >> t;
while(t--) {
ans = 0, i = 1;
for(int i=1; i<=3; i++) cin >> s[i];
cin >> v;
dfs(1);
printf("%.12lf\n", ans);
}
}