BZOJ #4832. 抵制克蘇恩
阿新 • • 發佈:2018-11-24
題意
場上有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;
}