您的位置:首页 > 其它

hdu 4649 (期望dp)

2013-08-07 10:07 344 查看
点击打开链接

题意:

给你n+1个数(a0-an),n个位运算(s1-sn),n个概率(p1-pn,pi表示第i个位运算符si和第i+1个数ai消失的概率),求期望

因为每个数字不超过2^20,所以可以压缩成二进制进行计算,求出每个数每一位上出现0或1的概率,然后乘以二进制位对应的十进制数就得到这一位的期望了,在把所有为的期望求和,就是所求。。

因为每次数次可能消失所以可以分为取与不取,不取两种情况

#include"stdio.h"
#include"string.h"
#define N 21
double dp
[N*10][2];
//dp[i][j][0]表示第j个数的第i位出现0的概率
//dp[i][j][1]表示第j个数的第i位出现1的概率
int main()
{
int t;
int n;
int i,j;
int A[N*10];
char s[N*10];
double p[N*10];
t=1;
while(scanf("%d",&n)!=-1)
{
for(i=0;i<=n;i++)
scanf("%d",&A[i]);
getchar();
for(i=1;i<=n;i++)
{
scanf("%c",&s[i]);
getchar();
}
for(i=1;i<=n;i++)
scanf("%lf",&p[i]);

memset(dp,0,sizeof(dp));
double ans=0;
for(i=0;i<=20;i++)
{
if(A[0]&(1<<i))dp[i][0][1]=1;
else dp[i][0][0]=1;
for(j=1;j<=n;j++)
{
//不取该位
dp[i][j][0]=dp[i][j-1][0]*p[j];
dp[i][j][1]=dp[i][j-1][1]*p[j];
//取该位
if(A[j]&(1<<i))//该位为1
{
if(s[j]=='&')
{
dp[i][j][1]+=dp[i][j-1][1]*(1-p[j]);
dp[i][j][0]+=dp[i][j-1][0]*(1-p[j]);
}
else if(s[j]=='|')
{
dp[i][j][1]+=dp[i][j-1][1]*(1-p[j]);
dp[i][j][1]+=dp[i][j-1][0]*(1-p[j]);
}
else
{
dp[i][j][1]+=dp[i][j-1][0]*(1-p[j]);
dp[i][j][0]+=dp[i][j-1][1]*(1-p[j]);
}
}
else//该位为0
{
if(s[j]=='&')
{
dp[i][j][0]+=dp[i][j-1][1]*(1-p[j]);
dp[i][j][0]+=dp[i][j-1][0]*(1-p[j]);
}
else if(s[j]=='|')
{
dp[i][j][1]+=dp[i][j-1][1]*(1-p[j]);
dp[i][j][0]+=dp[i][j-1][0]*(1-p[j]);
}
else
{
dp[i][j][1]+=dp[i][j-1][1]*(1-p[j]);
dp[i][j][0]+=dp[i][j-1][0]*(1-p[j]);
}
}
}
ans+=((1<<i)*dp[i]
[1]);
}
printf("Case %d:\n",t++);
printf("%.6f\n",ans);
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  期望dp hdu 多校联赛5