1152 - Expected value of the expression

Time Limit:2s Memory Limit:128MByte

Submissions:128Solved:63

DESCRIPTION

You are given an expression: A0O1A1O2A2OnAnA0O1A1O2A2⋯OnAn, where Ai(0in)Ai(0≤i≤n) represents number, Oi(1in)Oi(1≤i≤n) represents operator. There are three operators, &,|,^&,|,^, which means and,or,xorand,or,xor, and they have the same priority.

The ii-th operator OiOi and the numbers AiAi disappear with the probability of pipi.

Find the expected value of an expression.

INPUT
The first line contains only one integer n(1n1000)n(1≤n≤1000). The second line contains n+1n+1 integers Ai(0Ai<220)Ai(0≤Ai<220). The third line contains nn chars OiOi. The fourth line contains nn floats pi(0pi1)pi(0≤pi≤1).
OUTPUT
Output the excepted value of the expression, round to 6 decimal places.
SAMPLE INPUT
2
1 2 3
^ &
0.1 0.2
SAMPLE OUTPUT
2.800000
HINT
Probability = 0.1 * 0.2 Value = 1 Probability = 0.1 * 0.8 Value = 1 & 3 = 1 Probability = 0.9 * 0.2 Value = 1 ^ 2 = 3 Probability = 0.9 * 0.8 Value = 1 ^ 2 & 3 = 3 Expected Value = 0.1 * 0.2 * 1 + 0.1 * 0.8 * 1 + 0.9 * 0.2 * 3 + 0.9 * 0.8 * 3 = 2.80000
SOLUTION
题意:给你n+1个数,n个位运算符,第一个数到第n个数和对应的n个运算符一起消失的概率为p[i],问你运算结果的期望。
题解:dp[i][j][k]   前i个数 a[i]二进制第j位置填k的概率 具体看代码中的转移方程
  1 #pragma comment(linker, "/STACK:102400000,102400000")
  2 #include <bits/stdc++.h>
  3 #include <cstdlib>
  4 #include <cstdio>
  5 #include <iostream>
  6 #include <cstdlib>
  7 #include <cstring>
  8 #include <algorithm>
  9 #include <cmath>
 10 #include <cctype>
 11 #include <map>
 12 #include <set>
 13 #include <queue>
 14 #include <bitset>
 15 #include <string>
 16 #include <complex>
 17 #define ll long long
 18 #define mod 1000000007
 19 using namespace std;
 20 int n;
 21 char s[2000000];
 22 int a[2000];
 23 char o[2000];
 24 double p[2000];
 25 double dp[2000][22][2];
 26 int main()
 27 {
 28     scanf("%d",&n);
 29     for(int i=0;i<=n;i++){
 30         scanf("%d",&a[i]);
 31     }
 32     getchar();
 33     gets(s);
 34     int len=strlen(s);
 35     int res=1;
 36     for(int i=0;i<len;i++){
 37         if(s[i]!=' '){
 38          o[res++]=s[i];
 39          }
 40     }
 41     for(int i=1;i<=n;i++){
 42         scanf("%lf",&p[i]);
 43     }
 44     int now;
 45     for(int i=1;i<=21;i++){//初始化
 46         now=(a[0]>>(i-1));
 47         if(now%2==1){
 48             dp[0][i][1]=1.0;
 49             dp[0][i][0]=0.0;
 50         }
 51         else{
 52             dp[0][i][1]=0.0;
 53             dp[0][i][0]=1.0;
 54         }
 55     }
 56     for(int i=1;i<=n;i++){
 57         for(int j=1;j<=21;j++){
 58          dp[i][j][0]+=dp[i-1][j][0]*p[i];//消失
 59          dp[i][j][1]+=dp[i-1][j][1]*p[i];
 60         }
 61         if(o[i]=='^'){
 62             for(int j=1;j<=21;j++){//不消失
 63                 now=(a[i]>>(j-1));
 64                 if(now%2==1){
 65                     dp[i][j][1]+=dp[i-1][j][0]*(1.0-p[i]);
 66                     dp[i][j][0]+=dp[i-1][j][1]*(1.0-p[i]);
 67                 }
 68                 else
 69                 {
 70                     dp[i][j][1]+=dp[i-1][j][1]*(1.0-p[i]);
 71                     dp[i][j][0]+=dp[i-1][j][0]*(1.0-p[i]);
 72                 }
 73             }
 74         }
 75          if(o[i]=='|'){
 76                 for(int j=1;j<=21;j++){
 77                 now=(a[i]>>(j-1));
 78                 if(now%2==1){
 79                     dp[i][j][1]+=(dp[i-1][j][0]+dp[i-1][j][1])*(1.0-p[i]);               }
 80                 else
 81                 {
 82                     dp[i][j][1]+=dp[i-1][j][1]*(1.0-p[i]);
 83                     dp[i][j][0]+=dp[i-1][j][0]*(1.0-p[i]);
 84                 }
 85             }
 86 
 87         }
 88          if(o[i]=='&'){
 89                 for(int j=1;j<=21;j++){
 90                 now=(a[i]>>(j-1));
 91                 if(now%2==1){
 92                     dp[i][j][1]+=dp[i-1][j][1]*(1.0-p[i]);
 93                     dp[i][j][0]+=dp[i-1][j][0]*(1.0-p[i]);
 94                 }
 95                 else
 96                 {
 97                     dp[i][j][0]+=(dp[i-1][j][0]+dp[i-1][j][1])*(1.0-p[i]);
 98                 }
 99             }
100         }
101     }
102     double ans=0;
103     now=1;
104     for(int i=1;i<=21;i++){
105         ans=ans+(dp[n][i][1])*now;
106         now*=2;
107     }
108     printf("%.6f\n",ans);
109     return 0;
110 }