题目链接:Winning Streak UVA - 11176
题目大意:给出n和p,n场比赛,每一场比赛的获胜概率为p,求连胜的期望。
用dp[i][j]表示前i场比赛中,连胜不超过j的概率
那么对于第i场比赛来说,有以下两种情况:
1、 无论胜负都不会影响连胜场数
则dp[i][j]=dp[i-1][j]
2、 会对当前连胜造成影响
1> 若i=j+1,即当前全胜且已有j场连胜,那么需要减去第i场也获胜的概率
则dp[i][j]-=pp[j+1](pp[j]表示连胜j场的概率)
2> 若i>j+1,即在前i-1场中已有j场连胜,如果第i场获胜,那么连胜将变为j+1
则dp[i][j]-=dp[i-1-(j+1)][j]pp[j+1](1-p)
dp[i-1-(j+1)][j]表示在前i-1场里,除了已知的j场连胜,和j场连胜前必为负的那一场比赛外,再之前的场数中连胜小于等于j的概率
最后,用dp[n][j]-dp[n][j-1]来表示连胜为j场的概率
#include <iostream>
#include <cstdio>
using namespace std;
const int N=5e2+5;
double dp[N][N],pp[N];
double p;
int n;
int main()
{
while(~scanf("%d%lf",&n,&p)&&n)
{
pp[0]=1;
for(int i=0;i<=n;i++)
pp[i+1]=pp[i]*p,dp[0][i]=1;
for(int i=1;i<=n;i++)
for(int j=0;j<=n;j++)
{
dp[i][j]=dp[i-1][j];
if(i==j+1)
dp[i][j]-=pp[j+1];
else if(i>j+1)
dp[i][j]-=dp[i-1-(j+1)][j]*(1-p)*pp[j+1];
}
double ans=0;
for(int i=1;i<=n;i++)
ans+=(dp[n][i]-dp[n][i-1])*i;
printf("%.6lf\n",ans);
}
return 0;
}