• 【hdu 4696】Professor Tian


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

    Description

    给你一个由位运算“与”“或”“和”组成的计算表达式;
    每个运算符都有p[i]的几率消失;
    问你最后这个计算表达式的值的期望是多少?
    运算的数字< 220

    Solution

    因为二进制在进行位运算的时候,是不会产生进位的;
    因此,我们可以一位一位地算;
    即从二进制的第一位开始算,通过一个简单的DP,得到
    这一位在n个数字做完之后为1的概率是多少;
    然后乘上2^0即可;
    对于第二位,第三位…用同样的方法做即可;
    定义的状态为
    f[i][j][k]表示第i位,在前j个数算完之后,为k的概率是多少,k=0或者1;

    NumberOf WA

    0

    Reviw

    二进制在计算的时候,不会产生进位->各个位的计算是独立的;
    这里利用了一个独立的思想;

    Code

    #include <bits/stdc++.h>
    using namespace std;
    #define int long long
    using namespace std;
    
    const int M = 20;
    const int N = 200;
    
    double f[M+10][N+10][2],p[N+10],ans = 0;
    int two[M+10],n,a[N+10];
    char s[N+10][5];
    
    main(){
        //freopen("/home/ccy/rush.txt","r",stdin);
        two[0] = 1;
        for (int i = 1;i <= M;i++)
            two[i] = two[i-1]*2;
        int kk = 0;
        while(~scanf("%lld",&n)){
            ans = 0;
            for (int i = 1;i <= n+1;i++)
                scanf("%lld",&a[i]);
            for (int i = 1;i <= n;i++)
                scanf("%s",s[i]);
            for (int i = 1;i <= n;i++)
                scanf("%lf",&p[i]);
            for (int i = 0;i <= M-1;i++){
                int temp = two[i];
                if (a[1]&temp)
                    f[i][1][1] = 1,f[i][1][0] = 0;
                else
                    f[i][1][0] = 1,f[i][1][1] = 0;
                for (int j = 1;j <= n;j++){
                    if (a[j+1]&temp){
                        if (s[j][0]=='&'){
                            f[i][j+1][1] = f[i][j][1];
                            f[i][j+1][0] = f[i][j][0];
                        }
                        if (s[j][0]=='|'){
                            f[i][j+1][1] = f[i][j][1] + f[i][j][0]*(1-p[j]);
                            f[i][j+1][0] = f[i][j][0]*p[j];
                        }
                        if (s[j][0]=='^'){
                            f[i][j+1][1] = f[i][j][0]*(1-p[j]) + f[i][j][1]*p[j];
                            f[i][j+1][0] = f[i][j][1]*(1-p[j]) + f[i][j][0]*p[j];
                        }
                    }else{
                        //(a[j+1]&temp)==0
                        //a[j+1] in i  == 0
                        if (s[j][0]=='&'){
                            f[i][j+1][1] = f[i][j][1]*p[j];
                            f[i][j+1][0] = f[i][j][0] + f[i][j][1]*(1-p[j]);
                        }
                        if (s[j][0]=='|'){
                            f[i][j+1][1] = f[i][j][1];
                            f[i][j+1][0] = f[i][j][0];
                        }
                        if (s[j][0]=='^'){
                            f[i][j+1][1] = f[i][j][1];
                            f[i][j+1][0] = f[i][j][0];
                        }
                    }
                }
                ans = ans + 1.0*temp*f[i][n+1][1];
            }
            printf("Case %lld:
    %.6lf
    ",++kk,ans);
        }
        return 0;
    }
    
  • 相关阅读:
    CSS预编译:less入门
    JavaScript学习(五):函数表达式
    关于JavaScript new 的一些疑问
    JavaScript学习(四):面对对象的程序设计
    JavaScript学习(三):引用类型
    JavaScript学习(二):变量、作用域和内存问题
    JavaScript学习(一):基本概念
    匿名函数的this指向为什么是window?
    阿里云ECS在CentOS 6.8中使用Nginx提示:nginx: [emerg] socket() [::]:80 failed (97: Address family not supported by protocol)的解决方法
    Centos释放缓存
  • 原文地址:https://www.cnblogs.com/AWCXV/p/7626152.html
Copyright © 2020-2023  润新知