参考:
http://www.cnblogs.com/kuangbin/archive/2012/10/03/2710648.html
http://blog.csdn.net/morgan_xww/article/details/6775853
本题通过代换系数,化简后求系数。
一般形成环的用高斯消元法求解。但是此题都是和dp[0]相关。所有可以分离出系数。
/* ZOJ 3329 题意:有三个骰子,分别有k1,k2,k3个面。 每次掷骰子,如果三个面分别为a,b,c则分数置0,否则加上三个骰子的分数之和。 当分数大于n时结束。求游戏的期望步数。初始分数为0 设dp[i]表示达到i分时到达目标状态的期望,pk为投掷k分的概率,p0为回到0的概率 则dp[i]=∑(pk*dp[i+k])+dp[0]*p0+1; 都和dp[0]有关系,而且dp[0]就是我们所求,为常数 设dp[i]=A[i]*dp[0]+B[i]; 代入上述方程右边得到: dp[i]=∑(pk*A[i+k]*dp[0]+pk*B[i+k])+dp[0]*p0+1 =(∑(pk*A[i+k])+p0)dp[0]+∑(pk*B[i+k])+1; 明显A[i]=(∑(pk*A[i+k])+p0) B[i]=∑(pk*B[i+k])+1 先递推求得A[0]和B[0]. 那么 dp[0]=B[0]/(1-A[0]); */
const double eps = 1e-10;
const int MAXN = 600;
//double dp[MAXN][MAXN];
double A[MAXN];
double B[MAXN];
double p[MAXN];
int n, k1, k2, k3, a, b, c;
int main ()
{
int T;
RI(T);
while (T--)
{
RI(n);
RIII(k1, k2, k3);
RIII(a, b, c);
double p0 = 1.0 / k1 / k2 / k3;
CLR(p, 0);
for (int i = 1; i <= k1; i++)
for (int j = 1; j <= k2; j++)
for (int r = 1; r <= k3; r++)
{
if (i != a || j != b || r != c)
p[i + j + r] += p0;
}
CLR(A, 0);
CLR(B, 0);
for (int i = n; i >= 0; i--)
{
A[i] = p0;
B[i] = 1;
for (int j = 1; j + i <= n; j++)
{
A[i] += p[j] * A[j + i];
B[i] += p[j] * B[j + i];
}
}
printf("%.10lf\n", B[0] / (1 - A[0]));
}
return 0;
}