HDU 4649 - Professor Tian(概率DP)

来源:互联网 发布:java map value 多值 编辑:程序博客网 时间:2024/05/21 08:51

题目:

http://acm.hdu.edu.cn/showproblem.php?pid=4649

题意;

n+1个数, n个操作符, 每个操作符消失的概率为f,操作符消失时连同后面那个数消失.求出期望答案.

思路:

将每个数拆分成二进制位.

dp[i][j][0] :第i个数第j位取0的概率.

dp[i][j][1] :第i个数第j位取1的概率.

注意输出要 %.6f...

AC.

#include <iostream>#include <cstdio>#include <cstring>#include <cmath>using namespace std;int num[205], a[205][25];char c[205];double f[205];double dp[205][25][3];int main(){//freopen("in", "r", stdin);    int n, ca = 1;    while(~scanf("%d", &n)) {        for(int i = 0; i <= n; ++i) {            scanf("%d", &num[i]);        }        for(int i = 1; i <= n; ++i) {            getchar();            scanf("%c", &c[i]);        }        for(int i = 1; i <= n; ++i) {            scanf("%lf", &f[i]);        }        memset(a, 0, sizeof(a));        for(int i = 0; i <= n; ++i) {            int k = 0;            while(num[i] > 0) {                a[i][k++] = num[i]%2;                num[i] = num[i]/2;            }        }        memset(dp, 0, sizeof(dp));        for(int i = 0; i < 21; ++i) {            if(a[0][i] == 1) {                dp[0][i][1] = 1;            }            else {                dp[0][i][0] = 1;            }        }        for(int i = 1; i <= n; ++i) {            for(int j = 0; j < 21; ++j) {                dp[i][j][0] = dp[i-1][j][0]*f[i];                dp[i][j][1] = dp[i-1][j][1]*f[i];                if(c[i] == '|') {                    if(a[i][j] == 0) {                        dp[i][j][0] += dp[i-1][j][0]*(1-f[i]);                        dp[i][j][1] += dp[i-1][j][1]*(1-f[i]);                    }                    else if(a[i][j] == 1) {                        dp[i][j][1] += dp[i-1][j][0]*(1-f[i]) + dp[i-1][j][1]*(1-f[i]);                     }                }                if(c[i] == '^') {                    if(a[i][j] == 0) {                        dp[i][j][0] += dp[i-1][j][0]*(1-f[i]);                        dp[i][j][1] += dp[i-1][j][1]*(1-f[i]);                    }                    else if(a[i][j] = 1) {                        dp[i][j][0] += dp[i-1][j][1]*(1-f[i]);                        dp[i][j][1] += dp[i-1][j][0]*(1-f[i]);                    }                }                if(c[i] == '&') {                    if(a[i][j] == 0) {                        dp[i][j][0] += dp[i-1][j][0]*(1-f[i]) + dp[i-1][j][1]*(1-f[i]);                    }                    if(a[i][j] == 1) {                        dp[i][j][0] += dp[i-1][j][0]*(1-f[i]);                        dp[i][j][1] += dp[i-1][j][1]*(1-f[i]);                    }                }            }        }        double t = 1, ans = 0;        for(int i = 0; i < 21; ++i) {            ans += dp[n][i][1] * t;            t *= 2;        }        printf("Case %d:\n", ca++);        printf("%.6lf\n", ans);    }    return 0;}


0 0