【jzoj3661】【SHTSC2014】【概率充电器】【期望】

本文介绍了一款名为SHOI概率充电器的产品,并提出了一种计算该充电器中处于充电状态元件数量期望值的方法。通过从下至上及从上至下的概率计算策略,结合宽度优先搜索算法避免栈溢出问题,最终给出了具体实现代码。

题目大意

著名的电子产品品牌SHOI刚刚发布了引领世界潮流的下一代电子产品——概率充电器:
“采用全新纳米级加工技术,实现元件与导线能否通电完全由真随机数决定!SHOI概率充电器,您生活不可或缺的必需品!能充上电吗?现在就试试看吧!”
SHOI概率充电器由n-1条导线连通了n个充电元件。进行充电时,每条导线是否可以导电以概率决定,每一个充电元件自身是否直接进行充电也由概率决定。随后电能可以从直接充电的元件经过通电的导线使得其他充电元件进行间接充电。
作为SHOI公司的忠实客户,你无法抑制自己购买SHOI产品的冲动。在排了一个星期的长队之后终于入手了最新型号的SHOI概率充电器。你迫不及待地将SHOI概率充电器插入电源——这时你突然想知道,进入充电状态的元件个数的期望是多少呢?

解题思路

考虑计算充电的期望很复杂,考虑分别计算以1为根,从上到下,从下到上充不上电的概率。先计算从下到上,再计算从上到下即可。考虑到会爆栈,用bfs即可。

code

#include<cstdio>
#include<cmath>
#include<cstring>
#include<algorithm>
#define LF double
#define LL long long
#define ULL unsigned long long
#define fo(i,j,k) for(int i=j;i<=k;i++)
#define fd(i,j,k) for(int i=j;i>=k;i--)
#define fr(i,j) for(int i=begin[j];i;i=next[i])
using namespace std;
int const mn=5*1e5+9,mm=1e6+9,inf=1e9+7;
int n,gra,begin[mn],to[mm],next[mm],q[mn],inq[mn];
LF f[mn],g[mn],len[mm],a[mn];
void insert(int u,int v,LF w){
    to[++gra]=v;
    len[gra]=w;
    next[gra]=begin[u];
    begin[u]=gra;
}
int main(){
    //freopen("charger.in","r",stdin);
    //freopen("charger.out","w",stdout);
    freopen("d.in","r",stdin);
    freopen("d.out","w",stdout);
    scanf("%d",&n);
    fo(i,1,n-1){
        int a,b;LF p;
        scanf("%d%d%lf",&a,&b,&p),p/=100;
        insert(a,b,p);
        insert(b,a,p);
    }
    fo(i,1,n)scanf("%lf",&a[i]),a[i]/=100;
    int ti=0;
    inq[q[++ti]=1]=1;
    fo(i,1,n){
        int now=q[i];
        fr(j,now)if(!inq[to[j]])inq[q[++ti]=to[j]]=1;
    }
    fo(i,1,n)inq[i]=0;
    fd(i,n,1){
        int now=q[i];inq[now]=1;
        f[now]=1-a[now];
        fr(j,now)if(inq[to[j]]){
            f[now]*=1-len[j]*(1-f[to[j]]);
        }
    }
    g[1]=1;
    fo(i,1,n)inq[i]=0;
    fo(i,1,n){
        int now=q[i];inq[now]=1;
        fr(j,now)if(!inq[to[j]]){
            if(1-len[j]*(1-f[to[j]]))g[to[j]]=1-len[j]*(1-f[now]*g[now]/(1-len[j]*(1-f[to[j]])));
            else g[to[j]]=1-len[j];
        }
    }
    LF ans=0;
    fo(i,1,n)ans+=1-f[i]*g[i];
    printf("%.6lf",ans);
    return 0;
}
曾经发明了信号增幅仪的发明家 SHTSC 又公开了他的新发明:自动刷题机——一种可以自动 AC 题目的神秘装置。 自动刷题机刷题的方式非常简单:首先会瞬间得出题目的正确做法,然后开始写程序。每秒,自动刷题机的代码生成模块会有两种可能的结果: 写了 x x 行代码 心情不好,删掉了之前写的 y y 行代码。(如果 y y 大于当前代码长度则相当于全部删除。) 对于一个 OJ,存在某个固定的正整数长度 n n,一旦自动刷题机在某秒结束时积累了大于等于 n n 行的代码,它就会自动提交并 AC 此题,然后新建一个文件(即弃置之前的所有代码)并开始写下一题。SHTSC 在某个 OJ 上跑了一天的自动刷题机,得到了很多条关于写代码的日志信息。他突然发现自己没有记录这个 OJ 的 n n 究竟是多少。所幸他通过自己在 OJ 上的 Rank 知道了自动刷题机一共切了 k k 道题,希望你计算 n n 可能的最小值和最大值。 输入格式 第一行两个整数 l , k l,k,表示刷题机的日志一共有 l l 行,一共了切了 k k 题。 接下来 l l 行,每行一个整数 x i x i ​ ,依次表示每条日志。若 x i ≥ 0 x i ​ ≥0,则表示写了 x i x i ​ 行代码,若 x i < 0 x i ​ <0,则表示删除了 − x i −x i ​ 行代码。 输出格式 输出一行两个整数,分别表示 n n 可能的最小值和最大值。 如果这样的 n n 不存在,请输出一行一个整数 − 1 −1。
最新发布
11-22
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值