#include<iostream> #include<stdio.h> #include<algorithm> #include<cmath> #include<string.h> using namespace std; #define Maxn 210 int A[Maxn]; double p[Maxn]; char str[Maxn]; int Arr[Maxn][25]; double f[Maxn][2]; int n; void Bit(int x) //将当前位置的数转化为二进制 { int t=0; int tt=A[x]; while(tt){ Arr[x][t++]=tt&1; tt>>=1; } } void Solve(int x) { int i,j; memset(f,0,sizeof(f)); if(Arr[0][x]) f[0][1]=1; else f[0][0]=1; for(i=1;i<=n;i++) { f[i][1]=f[i-1][1]*p[i]; //若没出现,则当前位置01的概率既为上一位置的01的概率 f[i][0]=f[i-1][0]*p[i]; if(str[i]=='&'){ //根据&,|,^的结果算出当前01的概率 if(Arr[i][x]){ f[i][1]+=f[i-1][1]*(1-p[i]); f[i][0]+=f[i-1][0]*(1-p[i]); } else{ f[i][0]+=f[i-1][1]*(1-p[i]); f[i][0]+=f[i-1][0]*(1-p[i]); } } if(str[i]=='|'){ if(Arr[i][x]){ f[i][1]+=f[i-1][1]*(1-p[i]); f[i][1]+=f[i-1][0]*(1-p[i]); } else{ f[i][1]+=f[i-1][1]*(1-p[i]); f[i][0]+=f[i-1][0]*(1-p[i]); } } if(str[i]=='^'){ if(Arr[i][x]){ f[i][0]+=f[i-1][1]*(1-p[i]); f[i][1]+=f[i-1][0]*(1-p[i]); }else{ f[i][0]+=f[i-1][0]*(1-p[i]); f[i][1]+=f[i-1][1]*(1-p[i]); } } } } /*因为位运算不影响进位,所以只需要计算最终每一位出现1的概率,求解期望的时候,转化为10进制即可。 */ int main() { int i,j,tt=1; while(~scanf("%d",&n)){ memset(Arr,0,sizeof(Arr)); for(i=0;i<=n;i++) { scanf("%d",&A[i]); Bit(i); } getchar(); for(i=1;i<=n;i++) { str[i]=getchar(); getchar(); } for(i=1;i<=n;i++) scanf("%lf",&p[i]); double ans=0; int tmp=1; for(i=0;i<20;i++){ Solve(i); ans+=tmp*f[n][1]; tmp<<=1; } printf("Case %d:\n",tt++); printf("%0.6lf\n",ans); } return 0; }
hdu 4696 反状态压缩+动态规划
最新推荐文章于 2022-01-07 21:21:47 发布