版权声明:转载请注明出处 https://blog.csdn.net/qq_41593522/article/details/84402917
题意
场上有1血,2血,3血随从,总数不超过7,外加一个英雄
每次克苏恩会等概率攻击一个人,若随从被打一下还没死,且场上随从<7,那么会有一个3血随从
问英雄收到的伤害的期望值
题解
概率Dp,p[i][a][b][c]表示攻击到第i次,场上有1血,2血,3血随从分别a,b,c个的概率
f[i][a][b][c]表示攻击到第i次,场上有1血,2血,3血随从分别a,b,c个时英雄收到伤害的期望值
调试记录
判断随从是否<7时没把a,b算上
#include <cstdio>
#include <cstring>
#include <algorithm>
#define maxn 105
using namespace std;
long double p[maxn][8][8][8], f[maxn][8][8][8];
int k, A, B, C, T;
int main(){
scanf("%d", &T);
while (T--){
scanf("%d%d%d%d", &k, &A, &B, &C);
memset(f, 0, sizeof f);
memset(p, 0, sizeof p);
p[0][A][B][C] = 1.0;
for (int i = 0; i < k; i++){
for (int a = 0; a <= 7; a++){
for (int b = 0; a + b <= 7; b++){
for (int c = 0; a + b + c <= 7; c++){
long double P = (long double)1.0 / (a + b + c + 1);
if (a != 0){
f[i + 1][a - 1][b][c] += f[i][a][b][c] * P * a;
p[i + 1][a - 1][b][c] += p[i][a][b][c] * P * a;
}
if (b != 0){
f[i + 1][a + 1][b - 1][min(a + b + c + 1, 7) - a - b] += f[i][a][b][c] * P * b;
p[i + 1][a + 1][b - 1][min(a + b + c + 1, 7) - a - b] += p[i][a][b][c] * P * b;
}
if (c != 0){
f[i + 1][a][b + 1][min(a + b + c + 1, 7) - a - b - 1] += f[i][a][b][c] * P * c;
p[i + 1][a][b + 1][min(a + b + c + 1, 7) - a - b - 1] += p[i][a][b][c] * P * c;
}
f[i + 1][a][b][c] += (f[i][a][b][c] + p[i][a][b][c]) * P;
p[i + 1][a][b][c] += p[i][a][b][c] * P;
}
}
}
}
long double ans = 0;
for (int a = 0; a <= 7; a++)
for (int b = 0; b <= 7; b++)
for (int c = 0; c <= 7; c++)
ans += f[k][a][b][c];
printf("%.2lf\n", (double)ans);
}
return 0;
}