lonlifeOJ1152 “玲珑杯”ACM比赛 Round #19 概率DP

E -- Expected value of the expression

 

 

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
 
 
题意:
  给你一个n+1个数进行位操作
  给你这个n+1个数(a0~an)和 进行的操作(异或,并,或) c[i]
  ci 和 ai同时消失的 概率是 pi
  求最后值得期望
题解:
  dp[i][25][0/1]
  表示前i个 数  0~21位上每一位存在(0/1)的概率,强推过去就行了
#include<bits/stdc++.h>
using namespace std;
#pragma comment(linker, "/STACK:102400000,102400000")
#define ls i<<1
#define rs ls | 1
#define mid ((ll+rr)>>1)
#define pii pair<int,int>
#define MP make_pair
typedef long long LL;
const long long INF = 1e18+1LL;
const double pi = acos(-1.0);
const int N = 5e3+10, M = 1e3+20,inf = 2e9;

int n,a[N];
char c[N];
double dp[N][30][2],p[N];
int main() {
    while(scanf("%d",&n)!=EOF) {
        for(int i = 0; i <= n; ++i) {
            scanf("%d",&a[i]);
        }
        memset(dp,0,sizeof(dp));
        for(int i = 1; i <= n; ++i) {
            getchar();
            scanf("%c",&c[i]);
        }
        for(int i = 1; i <= n; ++i) {
            scanf("%lf",&p[i]);
        }
        for(int i = 0; i <= 21; ++i) {
            if(((1<<i)&a[0])) dp[0][i][1] = 1,dp[0][i][0] = 0;
            else dp[0][i][0] = 1,dp[0][i][1] = 0;
        }
        for(int i = 1; i <= n; ++i) {

            for(int j = 0; j <= 21; ++j) {
                 dp[i][j][1] += 1.0*dp[i-1][j][1] * p[i];
                 dp[i][j][0] += 1.0*dp[i-1][j][0] * p[i];
            }
            for(int j = 0; j <= 21; ++j) {
                int tmp = ((a[i]>>j)&1);
                if(c[i] == '^') {
                    dp[i][j][tmp^1] += 1.0*dp[i-1][j][1]*(1.0-p[i]);
                    dp[i][j][tmp^0] += 1.0*dp[i-1][j][0]*(1.0-p[i]);
                }
                else if(c[i] == '&'){
                    dp[i][j][tmp&1] += 1.0*dp[i-1][j][1]*(1.0-p[i]);
                    dp[i][j][tmp&0] += 1.0*dp[i-1][j][0]*(1.0-p[i]);
                }
                else if(c[i] == '|') {
                    dp[i][j][tmp|1] += 1.0*dp[i-1][j][1]*(1.0-p[i]);
                    dp[i][j][tmp|0] += 1.0*dp[i-1][j][0]*(1.0-p[i]);
                }
            }
        }
        double ans = 0;
        for(int i = 0; i <= 21; ++i) {
            LL tmp = 1<<i;
            ans += (double)(dp[n][i][1]) * 1.0 * tmp;
        }
        printf("%.6f\n",ans);
    }
    return 0;
}

 

posted @ 2017-07-29 16:51  meekyan  阅读(197)  评论(0编辑  收藏  举报