您的位置:首页 > 其它

ZOJ3582-Back to the Past-概率dp

2016-02-21 23:14 295 查看
一共左右两排共2N盏灯,计算每排都亮M盏以上的期望。每天每盏灯有P的概率点亮。

dp[i][j]记录左边i盏右边j盏时的期望,从dp

往前推。//没学概率论写的好懵逼。

#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>

using namespace std;

const int maxn = 50+5;
int N,M;
double P,dp[maxn][maxn],Yes[maxn],No[maxn],C[maxn][maxn];

void init()
{
for(int i=0;i<=maxn;i++)
{
C[i][0] = C[i][i] = 1.0;
for(int j=1;j<i;j++)
C[i][j] = C[i-1][j-1]+C[i-1][j];
}
}

int main()
{
init();
while(scanf("%d%d%lf",&N,&M,&P))
{
if(N==0&&M==0) break;
//cout << P << endl;
memset(dp,0,sizeof dp);
Yes[0]=No[0]=1;
for(int i=1;i<=N;i++)
{
Yes[i] = Yes[i-1]*P;
No[i] = No[i-1]*(1.0-P);
}

for(int i=N;i>=0;i--)
{
for(int j=N;j>=0;j--)
{
if(i>=M&&j>=M) continue;
double sum = 0;
for(int x=0;x+i<=N;x++)
{
for(int y=0;y+j<=N;y++)
{
if(x==0&&y==0) continue;
if(N-i>=x&&N-j>=y)
sum += dp[x+i][y+j]*C[N-i][x]*Yes[x]*No[N-i-x]*C[N-j][y]*Yes[y]*No[N-j-y];
}
}
dp[i][j] = (sum+1.0)/(1.0-No[N-i]*No[N-j]);
}
}

printf("%.6f\n",dp[0][0]);
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: