标签:
http://acm.hdu.edu.cn/showproblem.php?pid=4649
2 1 2 3 ^ ^ 0.1 0.2 2 8 9 10 ^ ^ 0.5 0.78 1 1 2 & 0.5
Case 1: 0.720000 Case 2: 4.940000 Case 3: 0.500000
/**
hdu4649 概率dp
题目大意:给定一个位运算服连接的表达式,第i个运算符与其后面的数字共同出现和消失,其消失的概率的为pi,问该表达式最后的期望值为多少
解题思路:由于为运算没有进位的影响,用dp[i][j][0~1]表示前j个数第i位0或1的期望为多少,那么最后dp[i][n][1]*(1<<i)加入最终结果就好了,
状态转移方程详见代码
*/
#include <string.h>
#include <iostream>
#include <stdio.h>
#include <algorithm>
using namespace std;
int n,a[1003];
double dp[25][500][2],p[500];
char s[1003][2];
int main()
{
int tt=0;
while(~scanf("%d",&n))
{
for(int i=0; i<=n; i++)
{
scanf("%d",&a[i]);
}
for(int i=1; i<=n; i++)
{
scanf("%s",s[i]);
}
for(int i=1; i<=n; i++)
{
scanf("%lf",&p[i]);
}
double ans=0;
memset(dp,0,sizeof(dp));
for(int i=0; i<=20; i++)
{
if(a[0]&(1<<i))dp[i][0][1]=1;
else dp[i][0][0]=1;
for(int j=1; j<=n; j++)
{
///第j个符号以及其后面的数字不考虑
dp[i][j][0]+=dp[i][j-1][0]*p[j];
dp[i][j][1]+=dp[i][j-1][1]*p[j];
///第j个符号以及其后面的数字不考虑
if(a[j]&(1<<i))///第j个数的第i位为1
{
if(s[j][0]=='&')
{
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][0]=='|')
{
dp[i][j][1]+=dp[i][j-1][0]*(1-p[j]);
dp[i][j][1]+=dp[i][j-1][1]*(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///第j个数的第i位为0
{
if(s[j][0]=='&')
{
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][0]=='|')
{
dp[i][j][0]+=dp[i][j-1][0]*(1-p[j]);
dp[i][j][1]+=dp[i][j-1][1]*(1-p[j]);
}
else
{
dp[i][j][0]+=dp[i][j-1][0]*(1-p[j]);
dp[i][j][1]+=dp[i][j-1][1]*(1-p[j]);
}
}
}
ans+=(1<<i)*dp[i][n][1];
}
printf("Case %d:\n%.6lf\n",++tt,ans);
}
return 0;
}
版权声明:本文为博主原创文章,未经博主允许不得转载。
标签:
原文地址:http://blog.csdn.net/lvshubao1314/article/details/48024001