CF248E.Piglets Birthday-概率、DP

news/发布时间2024/5/17 19:25:04

link:https://codeforces.com/contest/248/problem/E

题意:有 \(n\) 个货架,第 \(i\) 个货架初始有 \(a_i\) 罐蜂蜜,有 \(q\) 次操作,每次操作从 \(u\) 货架上等概率地选出 \(k\) 罐蜂蜜,尝一口,再放到 \(v\) 货架上,然后询问期望有多少个货架,上面每罐蜂蜜都被尝过。

\(n,q\leq 10^5,a_i\leq 100,k\leq 5\).


看数据范围, \(k\leq 5\)…好像只看这个也不能想到什么,但首先要意识到这个应该是有用的。

吃蜂蜜当成打标记:\(i\) 货架有 \(a_i\) 个小球,初始标记都是 \(0\) ,每次等概率选 \(k\) 个,打上 \(1\) 的标记,放到 \(v\) 上。很明显,被放到 \(v\) 上的蜂蜜一定是打过标记的。
刚开始的时候我想的是对被打过标记的蜂蜜进行DP,\(f(i,j)\) 表示 \(i\) 货架上有 \(j\) 罐蜂蜜被打过标记(被尝过)的概率,一次转移是 \(O(k\times a_i)\) 的,但这样复杂度是不对的,比如把很多罐蜂蜜都放到一个货架上, \(a_i\) 会长到 1e5 的范围,然后再把这些蜂蜜转移到其他地方,复杂度就爆炸了。

所以DP的时候也应当注意到这样一个关系,打过标记的蜂蜜越来越多,没打过标记的越来越少,同时,对每个货架来说,没被打过标记的也是越来越少的。

因此应该让 \(f(i,j)\) 表示,\(i\) 货架有 \(j\) 罐蜂蜜打过标记的概率,答案是 \(\sum f(i,0)\),转移则只要考虑 \(u\)

\[\frac{\binom{j}{i}\times \binom{a-j}{k-i}}{\binom{a}{k}}\cdot f(v,j)\to f_{new}(v,j-i) \]

预处理组合数(第二维 \(\leq k\)\(O(\max a_i\times k)\) 暴力处理就好),\(O(\max a_i \times k)\) 地转移

#include<bits/stdc++.h>
#define rep(i,a,b) for(int i=(a);i<=(b);i++)
#define endl '\n'
#define fastio ios_base::sync_with_stdio(false);cin.tie(0);cout.tie(0)
using namespace std;
const int N=1e5+5;
const int C=105;
const int MX=5e5+50;
int n,q,a[N],mx[N];
double f[N][C],g[C],binom[MX][6];
int main(){fastio;cin>>n;rep(i,1,n){cin>>a[i];mx[i]=a[i];f[i][a[i]]=1;}rep(i,0,MX-5){binom[i][0]=1;rep(j,1,min(i,5))binom[i][j]=binom[i-1][j]+binom[i-1][j-1];}double ans=0;rep(i,1,n)ans+=f[i][0];cin>>q;while(q--){int u,v,k;cin>>u>>v>>k;ans-=f[u][0];rep(i,0,mx[u]){g[i]=f[u][i];f[u][i]=0;}rep(j,0,mx[u])rep(x,0,k)f[u][j-x]+=binom[j][x]*binom[a[u]-j][k-x]/binom[a[u]][k]*g[j];a[u]-=k;a[v]+=k;ans+=f[u][0];cout<<fixed<<setprecision(12)<<ans<<endl;}return 0;
}

顺带一提-Vandermonde卷积

上面DP转移里出现了转移系数:枚举状态 \(f(v,j)\) 的所有转移,所有转移的概率之和必然是 \(1\),那么有:

\[\sum_{i}\binom{j}{i}\times \binom{a-j}{k-i}=\binom{a}{k} \]

这个就是Vandermonde卷积公式啦,用题目中的例子就可以很好地解释其组合含义:有 \(a\) 个小球,有 \(j\) 个是好的,\(a-j\) 个是坏的,从中无序地选出 \(k\) 个,共有 \(\binom{a}{k}\) 种选择方式,而从另一角度考虑:枚举选了 \(i\) 个好球和 \(k-i\) 个坏球,算出来的方案自然是一样的。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.ulsteruni.cn/article/32273301.html

如若内容造成侵权/违法违规/事实不符,请联系编程大学网进行投诉反馈email:xxxxxxxx@qq.com,一经查实,立即删除!

相关文章

认知提升的方法

认知提升的方法一、什么是认知 经验是对于过往经历的总结归纳,当把这种经验传授给别人时,这种经验对别人来说就是知识。所以,知识是人脑对客观事物的信息沉淀。 技能是人们通过练习而获得的动作方式和系统,例如操作技能中的PS技术、木工技术、电工技术、水工技术等,而能力…

将社会脆弱性纳入高分辨率全球洪水风险绘图

贡献 将高分辨率流洪水模型的年平均超标概率估计值与网格化人口和贫困数据相结合,创建了 90 米分辨率的全球洪水脆弱性调整风险指数(VARI Flood)。该指数提供了国家内部或国家之间相对风险的估计值,并通过识别以高密度和高社会脆弱性为特征的 "热点地区",改变了…

acwing351

https://www.acwing.com/activity/content/problem/content/9051/ NOIP2007提高组T4。本题是加强版。 题目描述 设 \(T=(V, E, W)\) 是一个无圈且连通的无向图(也称为无根树),每条边带有正整数的权,我们称 \(T\) 为树网(treenetwork),其中 \(V, E\) 分别表示结点与边的集…

Unity热更学习笔记--AB包的依赖 0.98

AB包的依赖 接上一小结。 在这里我们新建一个红色材质球,赋值给Cube预制体。此时不对材质球进行AB包分类,再次进行打包。运行脚本,发现红色cube成功的从AB包中加载出来。尽管我们没有将cube所依赖的材质球进行打包分类,但是打包时候unity会自动将包中的物体相关依赖打入包中…

Y2 知识和题单

Link。 0x01 进制 引入 计数原理,对于 \(N\) 进制,那么就是逢 \(N\) 进一。 计算机中常用二进制,对应电路中的通电(\(1\))断电(\(0\))。 人类从远古以来使用十进制。 常用的有二进制、三进制、八进制、十进制、十六进制等。 由于不同进制之间数值写法可能相同,在没有特…

Clock Switch,芯片时钟切换的毛刺是什么,如何消除

背景 芯片运行过程中需要时钟切换时,要考虑到是否会产生glitch,小小的glitch有可能导致电路运行的错误。所以时钟切换时需要特别的处理。 直接使用MUX进行时钟切换或者采用如下电路结构进行时钟切换:assign outclock = (clk1 & select) | (~select & clk0);或 assig…