【UOJ#390】【UNR#3】百鸽笼(动态规划,容斥)
【UOJ#390】【UNR#3】百鸽笼(动态规划,容斥)
题面
题解
发现这就是题解里说的:“火山喷发概率问题”(大雾
考虑如果是暴力的话,你需要记录下当前每一个位置的鸽笼数量,因为概率会随着你空的鸽笼的数量而变化。
我们可以把这个问题转变为给一个长度为\(N\)的序列填数的问题。
直接算似乎不是很好算(因为直接算是要钦定在最后,那么其他的东西放满之后每个位置被选择的概率会被改变),我们把最后一个被填满的恰好是\(i\),变成至少有一个集合\(S\)在\(i\)后面被填满。
因为是容斥,其他集合怎么样是无所谓的,所以可以直接丢掉;而\(S\)集合都要在\(i\)后面被填满,所以\(i\)是第一个被填满的,而\(i\)被填满后后面的概率也无所谓,为\(1\),前面又没有减少可以填的数的个数,所以每次填的概率也是一样的。假设\(i\)用完之后的长度为\(L\),那么前面的概率就是\(\frac{1}{(|S|+1)^L}\)。
这样子我们枚举集合之后,枚举集合中一个元素的出现次数,再记录一下总长度什么的,就可以进行转移了。
继续发现上面这个容斥过程中,最终的贡献之和\(|S|\)以及\(L\)相关,所以考虑只记录这两个东西进行转移,就可以优化掉集合的枚举。
然后对于\(n\)个位置每个位置都要算一遍答案,这个很不优秀,发现算两个不同位置的时候只需要在当前背包把新位置的贡献给删掉,再把之前位置的贡献给加进来就好了。
这样子每次位置只会进入背包两次,出背包一次。
复杂度为\(O(n^5)\)。
#include<iostream>
#include<cstdio>
using namespace std;
#define MOD 998244353
void add(int &x,int y){x+=y;if(x>=MOD)x-=MOD;}
inline int read()
{
int x=0;bool t=false;char ch=getchar();
while((ch<'0'||ch>'9')&&ch!='-')ch=getchar();
if(ch=='-')t=true,ch=getchar();
while(ch<='9'&&ch>='0')x=x*10+ch-48,ch=getchar();
return t?-x:x;
}
int n,N,a[35],C[950][950],f[35][950],ipw[35][950];
int fpow(int a,int b){int s=1;while(b){if(b&1)s=1ll*s*a%MOD;a=1ll*a*a%MOD;b>>=1;}return s;}
void Insert(int n,int sum,int a)
{
for(int i=n-1;~i;--i)
for(int j=sum;~j;--j)
if(f[i][j])
for(int k=0;k<a;++k)
add(f[i+1][j+k],MOD-1ll*f[i][j]*C[j+k][k]%MOD);
}
void Del(int n,int sum,int a)
{
for(int i=0;i<n;++i)
for(int j=0;j<=sum-a;++j)
if(f[i][j])
for(int k=0;k<a;++k)
add(f[i+1][j+k],1ll*f[i][j]*C[j+k][k]%MOD);
}
int main()
{
n=read();
for(int i=1;i<=n;++i)N+=(a[i]=read());
for(int i=1;i<=n;++i)ipw[i][0]=1;
for(int i=1;i<=n;++i)
for(int j=1,inv=fpow(i,MOD-2);j<=N;++j)
ipw[i][j]=1ll*ipw[i][j-1]*inv%MOD;
for(int i=0;i<=N;++i)C[i][0]=1;
for(int i=1;i<=N;++i)
for(int j=1;j<=i;++j)
C[i][j]=(C[i-1][j]+C[i-1][j-1])%MOD;
f[0][0]=1;
for(int i=1,s=0;i<=n;++i)Insert(i,s,a[i]),s+=a[i];
for(int i=1;i<=n;++i)
{
Del(n,N,a[i]);
int ret=0;
for(int j=0;j<n;++j)
for(int k=0;k<=N-a[i];++k)
if(f[j][k])
add(ret,1ll*f[j][k]*ipw[j+1][k+a[i]]%MOD*C[k+a[i]-1][a[i]-1]%MOD);
printf("%d ",ret);
Insert(n,N-a[i],a[i]);
}
puts("");return 0;
}
【UOJ#390】【UNR#3】百鸽笼(动态规划,容斥)的更多相关文章
- 【BZOJ4559】[JLoi2016]成绩比较 动态规划+容斥+组合数学
[BZOJ4559][JLoi2016]成绩比较 Description G系共有n位同学,M门必修课.这N位同学的编号为0到N-1的整数,其中B神的编号为0号.这M门必修课编号为0到M-1的整数.一 ...
- UOJ #390. 【UNR #3】百鸽笼
UOJ #390. [UNR #3]百鸽笼 题目链接 看这道题之前先看一道相似的题目 [PKUWC2018]猎人杀. 考虑类似的容斥: 我们不妨设处理\(1\)的概率. 我们令集合\(T\)中的所有鸽 ...
- 【BZOJ4455】小星星(动态规划,容斥)
[BZOJ4455]小星星(动态规划,容斥) 题面 BZOJ 洛谷 Uoj 题解 题意说简单点就是给定一张\(n\)个点的图和一棵\(n\)个点的树,现在要让图和树之间的点一一对应,并且如果树上存在一 ...
- 【BZOJ5287】[HNOI2018]毒瘤(动态规划,容斥)
[BZOJ5287][HNOI2018]毒瘤(动态规划,容斥) 题面 BZOJ 洛谷 题解 考场上想到的暴力做法是容斥: 因为\(m-n\le 10\),所以最多会多出来\(11\)条非树边. 如果就 ...
- 【LOJ#2542】[PKUWC2018]随机游走(min-max容斥,动态规划)
[LOJ#2542][PKUWC2018]随机游走(min-max容斥,动态规划) 题面 LOJ 题解 很明显,要求的东西可以很容易的进行\(min-max\)容斥,那么转为求集合的\(min\). ...
- 【UOJ#422】【集训队作业2018】小Z的礼物(min-max容斥,轮廓线dp)
[UOJ#422][集训队作业2018]小Z的礼物(min-max容斥,轮廓线dp) 题面 UOJ 题解 毒瘤xzy,怎么能搬这种题当做WC模拟题QwQ 一开始开错题了,根本就不会做. 后来发现是每次 ...
- 【BZOJ2024】舞会(动态规划,容斥,高精度)
[BZOJ2024]舞会(动态规划,容斥,高精度) 题面 BZOJ 洛谷 题解 这种关系显然要先排序才不会不想影响. 设\(f[i][j]\)表示前\(i\)个女生中,选了\(j\)个女生配对,并且女 ...
- 【BZOJ2839】集合计数(容斥,动态规划)
[BZOJ2839]集合计数(容斥,动态规划) 题面 BZOJ 权限题 Description 一个有N个元素的集合有2^N个不同子集(包含空集),现在要在这2^N个集合中取出若干集合(至少一个),使 ...
- 【BZOJ3622】已经没有什么好害怕的了(动态规划,容斥)
[BZOJ3622]已经没有什么好害怕的了(动态规划,容斥) 题面 BZOJ 题解 很明显的,这类问题是要从至少变成恰好的过程,直接容斥即可. 首先我们要求的是(糖果>药片)=(药片>糖果 ...
随机推荐
- Redis深度历险,全面解析Redis14个核心知识点
本人免费整理了Java高级资料,涵盖了Java.Redis.MongoDB.MySQL.Zookeeper.Spring Cloud.Dubbo高并发分布式等教程,一共30G,需要自己领取. 传送门: ...
- 并发编程-epoll模型的探索与实践
前言 我们知道nginx的效率非常高,能处理上万级的并发,其之所以高效离不开epoll的支持, epoll是什么呢?,epoll是IO模型中的一种,属于多路复用IO模型; 到这里你应该想到了,sele ...
- ubuntu下查看本机IP地址
在终端输入: ifconfig -a 即可得解.出来的结果inet后就是你的ip地址
- ADB常用命令(adb常用命令)
基本用法 命令语法 adb 命令的基本语法如下: adb [-d|-e|-s <serialNumber>] <command> 如果只有一个设备/模拟器连接时,可以省略掉 [ ...
- MySQL 部署 MHA 高可用架构 (二)
实现 MHA VIP 功能 配置 master_ip_failover 脚本(db3) 把 master_ip_failover 上传到 /iba/software 上 master_ip_failo ...
- openresty安装笔记
目录 安装步骤: openresty安装在ubuntu下的安装 参考 安装OpenResty(Nginx+Lua)开发环境 安装步骤: # 创建目录/usr/servers,以后我们把所有软件安装在此 ...
- CodeForces - 1228D (暴力+思维+乱搞)
题意 https://vjudge.net/problem/CodeForces-1228D 有一个n个顶点m条边的无向图,在一对顶点中最多有一条边. 设v1,v2是两个不相交的非空子集,当满足以下条 ...
- Java面试中遇到的坑【篇二面试干货】
俗话说早起的鸟儿有虫吃,现在临年关越来越近,有跳槽的想法的同事也都打算年前做好功课年后入职,所谓年终奖拿了,工作换的也是水到渠成. 说到这里想必有同学要说了,年底了放着年终奖不拿为何要跳槽呢?这个就要 ...
- 2.Java基础_Java常量
/* 常量: 在程序执行过程中,其值不可以发生改变的量 常量分类: 字符串常量: 用双引号括起来的内容. "Hello,World!" 整数常量: 不带小数的数字. 666,-88 ...
- 9. Go语言—流程控制
一.流程控制语法 if condition_1{ }else if condition_2{ }else if condition_3{ }else{ } 二.switch分支 package mai ...