题意:
有三个骰子,每个骰子最大分别是k1,k2,k3;
现在投骰子,如果刚好第一个,第二个,第三个投出了a,b,c,就把总分数归0,否则三个点数计入总分数,直到分数大于n;
问期望的投骰子的次数;
思路:
E[I] 代表已经有了i分,还需要投的次数的期望;
那么可以得到E[i] = E[0] * P + Σ(E[i + k] * pk[k]) + 1;
那么我们可以设为E[I] = p1[I] * E[0] + p2[i];
则可以得到E[i] = Σ(p1[i + k] )+ p + Σ(p2[i + k]) + 1;
得到p1[i] = Σ(p1[i + k]) + p ; p2[i] = Σ(p2[i] + k) + 1;
就可以根据p1[0] ,p2[0] 算出E[0];
#include<cstdio>
#include<cstring>
const int N = 6 * 6 * 6;
double pk[N];
double p1[505];
double p2[505];
int n,k1,k2,k3,a,b,c;
int main() {
int t;
scanf("%d",&t);
while(t--){
memset(pk, 0, sizeof(pk));
memset(p1, 0, sizeof(p1));
memset(p2, 0, sizeof(p2));
scanf("%d%d%d%d%d%d%d",&n,&k1,&k2,&k3,&a,&b,&c);
double p = 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 == a && j == b && k == c)
continue;
pk[i+j+k] += p;
}
}
}
for(int i = n; i >= 0; i--){
for(int j = 3; j <= k1+k2+k3 && i+j <= n; j++){
p1[i] += p1[i + j] * pk[j];
p2[i] += p2[i + j] * pk[j];
}
p1[i] += p;
p2[i] += 1;
}
printf("%.15lf\n",p2[0]/(1 - p1[0]));
}
}