[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;
}
posted @ 2018-08-16 20:32  skylee03  阅读(155)  评论(0编辑  收藏  举报