ZOJ 3329 One Person Game 概率DP

做法:带环的概率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;
}


 

你可能感兴趣的:(ZOJ 3329 One Person Game 概率DP)