当前位置: 首页 > news >正文

UVA - 11181 Probability|Given(条件概率+状压dfs)

题目链接


设事件 A A A为: m m m个人买了东西,事件 B i B_i Bi为:第 i i i个人买了东西。显然要求的是条件概率 P ( B i ∣ A ) = P ( A B i ) P ( A ) P(B_i|A)= \frac{P(AB_i)}{P(A)} P(BiA)=P(A)P(ABi)

P ( A ) P(A) P(A)就是 n n n个人里面恰好有 m m m个状态为 1 1 1,那么我们考虑状压搜索;而 P ( A B i ) P(AB_i) P(ABi)是两事件同时发生的概率,那么就是满足 P ( A ) P(A) P(A)的合法状态里将每个为 1 1 1的人对应的 P ( A B i ) P(AB_i) P(ABi)累积,这样最后就能求出每个人的条件概率了

#include <set>
#include <map>
#include <stack>
#include <queue>
#include <math.h>
#include <cstdio>
#include <string>
#include <bitset>
#include <cstring>
#include <sstream>
#include <iostream>
#include <algorithm>
#include <unordered_map>
using namespace std;
#define fi first
#define se second
#define pb push_back
#define ins insert
#define lowbit(x) (x&(-x))
#define mkp(x,y) make_pair(x,y)
#define mem(a,x) memset(a,x,sizeof a);
typedef long long ll;
typedef long double ld;
typedef unsigned long long ull;
typedef pair<int,int> P;
const double eps=1e-8;
const double pi=acos(-1.0);
const int inf=0x3f3f3f3f;
const ll INF=1e18;
const int Mod=1e9+7;
const int maxn=2e5+10;

int n,m;

double sum;
bool vis[1<<21];
int num[1<<21];
double p[25],ans[25];

int cal(int x){  //计算x中有多少1
    int cnt=0;
    while(x){
        if(x&1) cnt++;
        x>>=1;
    }
    return cnt;
}

double solve(int x){  //计算状态x(例如10110)对应的概率
    double res=1.0;
    int y=x;
    for(int i=0;i<n;i++){
        if(x&1) res*=p[i];
        else res*=1.0-p[i];
        x>>=1;
    }
    for(int i=0;i<n && y;i++){  //将其中状态为1的位的P(AB)加上当前概率
        if(y&1) ans[i]+=res;
        y>>=1;
    }
    return res;
}

void dfs(int s){
    if(vis[s]) return;
    vis[s]=1;
    if(num[s]>m) return;
    if(num[s]==m){
        sum+=solve(s);
        return;
    }
    for(int i=0;i<n;i++) if(!(s&(1<<i))){
        dfs(s|(1<<i));
    }
}

int main(){
    //freopen("in.txt","r",stdin);
    //freopen("out.txt","w",stdout);
    //ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
    for(int i=0;i<(1<<20);i++)
        num[i]=cal(i);
    int kase=0;
    while(~scanf("%d%d",&n,&m) && n){
        for(int i=0;i<n;i++) scanf("%lf",&p[i]);
        memset(vis,0,sizeof vis);
        memset(ans,0,sizeof ans);
        sum=0.0;    //sum不要忘记初始化
        dfs(0);
        printf("Case %d:\n",++kase);
        for(int i=0;i<n;i++)
            printf("%.6f\n",ans[i]/sum);
    }
    return 0;
}

相关文章:

  • UVA - 1637 Double Patience(全概率+记忆化搜索)
  • Oracle检查对象[第八章笔记]
  • 魔法数字(dfs/bfs)
  • Win32 OpenGL编程(8) 3D模型变换及其组合应用
  • 牛妹的春游(二维费用背包+技巧)
  • 2019 ICPC 南京区域赛 - C Digital Path(多段图DP)
  • 去年我们在哪儿?——09年SD2.0大会侧记(2)
  • 2019 CSP-J 纪念品(完全背包+思维)
  • 从MTK的BIN文件里提取图片资源
  • 无题(Floyd的理解)
  • 一个MTK的百叶窗特效
  • 无题(贪心+优先队列)
  • 大会轶事录——09年SD2.0大会侧记(3)
  • 卡特兰数
  • 洛谷 P2532 [AHOI2012]树屋阶梯(高精度卡特兰数)
  • 【JavaScript】通过闭包创建具有私有属性的实例对象
  • 【技术性】Search知识
  • Apache的基本使用
  • Fabric架构演变之路
  • Java程序员幽默爆笑锦集
  • JS实现简单的MVC模式开发小游戏
  • js数组之filter
  • Meteor的表单提交:Form
  • nodejs调试方法
  • Otto开发初探——微服务依赖管理新利器
  • Sass Day-01
  • Spring Boot MyBatis配置多种数据库
  • Xmanager 远程桌面 CentOS 7
  • 编写高质量JavaScript代码之并发
  • 分享一份非常强势的Android面试题
  • 个人博客开发系列:评论功能之GitHub账号OAuth授权
  • 关于 Linux 进程的 UID、EUID、GID 和 EGID
  • 基于组件的设计工作流与界面抽象
  • 记一次和乔布斯合作最难忘的经历
  • 开放才能进步!Angular和Wijmo一起走过的日子
  • 探索 JS 中的模块化
  • 译米田引理
  • 这几个编码小技巧将令你 PHP 代码更加简洁
  • 06-01 点餐小程序前台界面搭建
  • #多叉树深度遍历_结合深度学习的视频编码方法--帧内预测
  • (8)STL算法之替换
  • (附源码)springboot课程在线考试系统 毕业设计 655127
  • (附源码)计算机毕业设计ssm电影分享网站
  • (六)Hibernate的二级缓存
  • (六)激光线扫描-三维重建
  • (数位dp) 算法竞赛入门到进阶 书本题集
  • ... 是什么 ?... 有什么用处?
  • ./indexer: error while loading shared libraries: libmysqlclient.so.18: cannot open shared object fil
  • .bat批处理(四):路径相关%cd%和%~dp0的区别
  • .net core webapi 部署iis_一键部署VS插件:让.NET开发者更幸福
  • .NetCore Flurl.Http 升级到4.0后 https 无法建立SSL连接
  • .net打印*三角形
  • .NET建议使用的大小写命名原则
  • .Net下的签名与混淆
  • /proc/stat文件详解(翻译)