http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=3329
概率正推,期望逆推。p[i]为得到i分的概率
E[i]为当前分数i到游戏结束n的期望步数
E[n]=0;
E[n-1]=p[1]*E[n]+p[0]*E[0]+1
E[n-2]=p[2]*E[n]+p[1]*E[n-1]+p[0]*E[0]+1;
.......
E[i]=Σ(1,k1+k2+k3)(p[k]*E[i+k))+p[0]*E[0]+1; (玄学递推式)
设E[i]=A[i]*E[0]+B[i];
将代数式代入递推式得
E[i]=(Σ(p(k)A[i+k])+1)*E[0]+Σ(p[k]B[i+k])+1
A[i]=Σ(p(k)A[i+k])+1;
B[i]=Σ(p[k]B[i+k])+1
E[0]=A[0]*E[0]+B[0];
E[0]=B[0]/(1-A[0]);
#include<iostream>
#include<cstdio>
#include<set>
#include<string>
#include<string.h>
#include<cstring>
#include<vector>
#include<map>
#include<queue>
#include<stack>
#include<cctype>
#include<algorithm>
#include<sstream>
#include<utility>
#include<cmath>
#define mt(a) memset(a,0,sizeof (a))
#define fl(a,b,c) fill(a,b,c)
#define SWAP(a,b,t) (t=a,a=b,b=t)
#define inf 1000000000+7
using namespace std;
typedef long long LL;
typedef long long ll;
double E[550],A[550],B[550],p[50];
int main()
{
int T;
cin >> T;
while (T--)
{
int n, k1, k2, k3, x, y, z;
scanf("%d %d %d %d %d %d %d", &n, &k1, &k2, &k3, &x, &y, &z);
mt(E);
mt(A);
mt(B);
mt(p);
double p0 = 1.0 / k1 / k2 / k3;
for (int i = 1; i <= k1; i++)
{
for (int j = 1; j <= k2; j++)
{
for (int k = 1; k <= k3; k++)
{
if (i == x&&j == y&&k == z)continue;
p[i + j + k] += 1.0 / k1 / k2 / k3;
}
}
}
for (int i = n; i >= 0; i--)
{
A[i] = p0; B[i] = 1;
for (int j = 1; j <= k1 + k2 + k3; j++)
{
A[i] += (A[i + j]*p[j]); B[i] += (B[i + j]*p[j]);
}
}
printf("%.16lf\n", B[0] / (1 - A[0]));
}
return 0;
}