[BZOJ4832]抵制克苏恩

[BZOJ4832]抵制克苏恩

思路:

\(f[i][j][k][l]\)表示打了\(i\)次,血量为\(1\sim 3\)的随从有\(j,k,l\)个的期望。转移时注意避免重复。

源代码:

#include<cstdio>
#include<cctype>
#include<cstring>
inline int getint() {
    register char ch;
    while(!isdigit(ch=getchar()));
    register int x=ch^'0';
    while(isdigit(ch=getchar())) x=(((x<<2)+x)<<1)+(ch^'0');
    return x;
}
const int N=50,M=8;
double f[N][M][M][M];
int main() {
    for(register int i=1;i<N;i++) {
        for(register int j=0;j<M;j++) {
            for(register int k=0;k<M-j;k++) {
                for(register int l=0;l<M-j-k;l++) {
                    const bool flag=j+k+l<7;
                    f[i][j][k][l]+=(f[i-1][j][k][l]+1)/(1+j+k+l);
                    if(j!=0) f[i][j][k][l]+=f[i-1][j-1][k][l]*j/(1+j+k+l);
                    if(k!=0) f[i][j][k][l]+=f[i-1][j+1][k-1][l+flag]*k/(1+j+k+l);
                    if(l!=0) f[i][j][k][l]+=f[i-1][j][k+1][l-1+flag]*l/(1+j+k+l);
                }
            }
        }
    }
    for(register int T=getint();T;T--) {
        const int n=getint(),a=getint(),b=getint(),c=getint();
        printf("%.2f\n",f[n][a][b][c]);
    }
    return 0;
}

猜你喜欢

转载自www.cnblogs.com/skylee03/p/9489654.html