做法:带环的概率DP,可是要用递推做...
很容易得出
dp[i]=sigma(p[j]*dp[i+j])+1+p0*dp[0] {i<n,i+j<=n}
dp[n]=1+p0*dp[0]
哎,然后只能去看看大神的题解了...
这里可以发现,dp[n]中只有变量dp[0],先让到最后dp[i]=x[i]*dp[0]+y[i];{0<=i<=n}
#include<cstdio> #include<cstring> const int LMT=520; double x[LMT],y[LMT],psi[LMT],p0; void init(void) { memset(x,0,sizeof(x)); memset(y,0,sizeof(y)); memset(psi,0,sizeof(psi)); } int main(void) { int T,n,a,b,c,k1,k2,k3,end; int i,ii,iii,j; scanf("%d",&T); while(T--) { init(); scanf("%d%d%d%d%d%d%d",&n,&k1,&k2,&k3,&a,&b,&c); for(i=1;i<=k1;++i) for(ii=1;ii<=k2;++ii) for(iii=1;iii<=k3;++iii) psi[i+ii+iii]+=1.0/(k1*k2*k3); end=k1+k2+k3; psi[a+b+c]-=1.0/(k1*k2*k3); p0=1.0/(k1*k2*k3); for(i=n;i>=0;i--) { for(j=3;j<=end;j++) { x[i]+=psi[j]*x[i+j]; y[i]+=psi[j]*y[i+j]; } x[i]+=p0; ++y[i]; } printf("%.15lf\n",y[0]/(1-x[0])); } return 0; }