题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4089
题意:n个人排成一队,小白排在第m个。对于队头的人,有四种可能:
(1)概率p1,保持不动;
(2)概率p2,换到队尾,第二个人成为队头;
(3)概率p3,走了,再也不回来了,第二个人成为队头;
(4)概率p4,游戏结束。
求结束时小白的排名小于等于K的概率。
思路:设dp[i][j]表示i个人的队,小白在第j个,此状态到达满足题意状态时的概率。那么dp[n][m]就是答案。
j=1,dp[i][j]=p1*dp[i][j]+p2*dp[i][i]+p4
2<=j<=k,dp[i][j]=p1*dp[i][j]+p2*dp[i][j-1]+p3*dp[i-1][j-1]+p4
j>k,dp[i][j]=p1*dp[i][j]+p2*dp[i][j-1]+p3*dp[i-1][j-1]
我们令p21=p2/(1-p1),p31=p3/(1-p1),p41=p4/(1-p1),那么有:
j=1,dp[i][j]=p21*dp[i][i]+p41
2<=j<=k,dp[i][j]=p21*dp[i][j-1]+p31*dp[i-1][j-1]+p41
j>k,dp[i][j]=p21*dp[i][j-1]+p31*dp[i-1][j-1]
如果我们从小到大计算dp[i],那么在计算dp[i]的时候dp[i-1]是已知的,将dp[i-1]作为常数,不妨设为c,那么我们有:
j=1,c[j]=p41
2<=j<=k,c[j]=p31*dp[i-1][j-1]+p41
j>k,c[j]=p31*dp[i-1][j-1]
这样化为:
j=1,dp[i][j]=p21*dp[i][i]+c[j]
2<=j<=k,dp[i][j]=p21*dp[i][j-1]+c[j]
j>k,dp[i][j]=p21*dp[i][j-1]+c[j]
这样就是一个方程组。下面解之。
int n,m,K;
double p1,p2,p3,p4,dp[N][N],Pow[N],c[N];
int main()
{
Rush(n)
{
RD(m,K); RD(p1,p2,p3,p4);
if(p4<EPS)
{
puts("0.00000");
continue;
}
double p21=p2/(1-p1),p41=p4/(1-p1),p31=p3/(1-p1);
int i,j;
Pow[0]=1;
FOR1(i,n) Pow[i]=Pow[i-1]*p21;
dp[1][1]=p41/(1-p21);
double temp;
FOR(i,2,n)
{
c[1]=p41;
FOR(j,2,K) c[j]=p31*dp[i-1][j-1]+p41;
FOR(j,K+1,i) c[j]=p31*dp[i-1][j-1];
temp=0;
FOR1(j,i) temp+=c[j]*Pow[i-j];
dp[i][i]=temp/(1-Pow[i]);
dp[i][1]=p21*dp[i][i]+c[1];
FOR(j,2,i) dp[i][j]=p21*dp[i][j-1]+c[j];
}
PR(dp[n][m]);
}
return 0;
}