传送门:HDU-4649
题意:
给你一个式子A0O1A1O2A3....OnAn,第i位有pi的概率消失掉,要计算式子最后值的期望
题解:期望dp
每个数二进制最多20位,我们维护每一位取0或取1的情况的概率,最后把为1的概率乘上1<<i再加起来即可
#include<bits/stdc++.h>
#define x first
#define y second
using namespace std;
typedef pair<int,int> PII;
const int MX = 1e3 + 5;
int n,x,cas=0;
int a[MX][20],b[MX];
char op[5];
double c[MX];
double dp[MX][20][2];
int main() {
//freopen("in.txt","r",stdin);
while (~scanf("%d", &n)) {
for(int i=0;i<=n;i++){
scanf("%d",&x);
for(int j=0;j<20;j++)
a[i][j]=(x>>j&1);
}
for(int i=1;i<=n;i++) {
scanf("%s",op);
if(op[0]=='^') b[i]=0;
else if(op[0]=='&') b[i]=1;
else b[i]=2;
}
for(int i=1;i<=n;i++) scanf("%lf",&c[i]),c[i]=1-c[i];
memset(dp,0,sizeof(dp));
for(int i=0;i<20;i++) dp[0][i][a[0][i]]=1;
for(int i=1;i<=n;i++){
for(int j=0;j<20;j++){
if(b[i]==0)
for(int k=0;k<2;k++)
dp[i][j][k]+=dp[i-1][j][k^a[i][j]]*c[i];
if(b[i]==1) {
if(a[i][j]==0) dp[i][j][0]+=(dp[i-1][j][0]+dp[i-1][j][1])*c[i];
else {
dp[i][j][0]+=dp[i-1][j][0]*c[i];
dp[i][j][1]+=dp[i-1][j][1]*c[i];
}
}
if(b[i]==2){
if(a[i][j]==0) {
dp[i][j][0]+=dp[i-1][j][0]*c[i];
dp[i][j][1]+=dp[i-1][j][1]*c[i];
}
else{
dp[i][j][1]+=(dp[i-1][j][0]+dp[i-1][j][1])*c[i];
}
}
dp[i][j][0]+=dp[i-1][j][0]*(1-c[i]);
dp[i][j][1]+=dp[i-1][j][1]*(1-c[i]);
}
}
double ans=0;
for(int j=0;j<20;j++) ans+=(1<<j)*dp[n][j][1];
printf("Case %d:\n%.6f\n",++cas,ans);
}
return 0;
}