【UOJ#390】【UNR#3】百鸽笼(动态规划,容斥)

题面

UOJ

题解

发现这就是题解里说的:“火山喷发概率问题”(大雾

考虑如果是暴力的话,你需要记录下当前每一个位置的鸽笼数量,因为概率会随着你空的鸽笼的数量而变化。

我们可以把这个问题转变为给一个长度为\(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】百鸽笼(动态规划,容斥)的更多相关文章

  1. 【BZOJ4559】[JLoi2016]成绩比较 动态规划+容斥+组合数学

    [BZOJ4559][JLoi2016]成绩比较 Description G系共有n位同学,M门必修课.这N位同学的编号为0到N-1的整数,其中B神的编号为0号.这M门必修课编号为0到M-1的整数.一 ...

  2. UOJ #390. 【UNR #3】百鸽笼

    UOJ #390. [UNR #3]百鸽笼 题目链接 看这道题之前先看一道相似的题目 [PKUWC2018]猎人杀. 考虑类似的容斥: 我们不妨设处理\(1\)的概率. 我们令集合\(T\)中的所有鸽 ...

  3. 【BZOJ4455】小星星(动态规划,容斥)

    [BZOJ4455]小星星(动态规划,容斥) 题面 BZOJ 洛谷 Uoj 题解 题意说简单点就是给定一张\(n\)个点的图和一棵\(n\)个点的树,现在要让图和树之间的点一一对应,并且如果树上存在一 ...

  4. 【BZOJ5287】[HNOI2018]毒瘤(动态规划,容斥)

    [BZOJ5287][HNOI2018]毒瘤(动态规划,容斥) 题面 BZOJ 洛谷 题解 考场上想到的暴力做法是容斥: 因为\(m-n\le 10\),所以最多会多出来\(11\)条非树边. 如果就 ...

  5. 【LOJ#2542】[PKUWC2018]随机游走(min-max容斥,动态规划)

    [LOJ#2542][PKUWC2018]随机游走(min-max容斥,动态规划) 题面 LOJ 题解 很明显,要求的东西可以很容易的进行\(min-max\)容斥,那么转为求集合的\(min\). ...

  6. 【UOJ#422】【集训队作业2018】小Z的礼物(min-max容斥,轮廓线dp)

    [UOJ#422][集训队作业2018]小Z的礼物(min-max容斥,轮廓线dp) 题面 UOJ 题解 毒瘤xzy,怎么能搬这种题当做WC模拟题QwQ 一开始开错题了,根本就不会做. 后来发现是每次 ...

  7. 【BZOJ2024】舞会(动态规划,容斥,高精度)

    [BZOJ2024]舞会(动态规划,容斥,高精度) 题面 BZOJ 洛谷 题解 这种关系显然要先排序才不会不想影响. 设\(f[i][j]\)表示前\(i\)个女生中,选了\(j\)个女生配对,并且女 ...

  8. 【BZOJ2839】集合计数(容斥,动态规划)

    [BZOJ2839]集合计数(容斥,动态规划) 题面 BZOJ 权限题 Description 一个有N个元素的集合有2^N个不同子集(包含空集),现在要在这2^N个集合中取出若干集合(至少一个),使 ...

  9. 【BZOJ3622】已经没有什么好害怕的了(动态规划,容斥)

    [BZOJ3622]已经没有什么好害怕的了(动态规划,容斥) 题面 BZOJ 题解 很明显的,这类问题是要从至少变成恰好的过程,直接容斥即可. 首先我们要求的是(糖果>药片)=(药片>糖果 ...

随机推荐

  1. CENTOS 7 升级内核版本(附带升级脚本)

    写在前面的话 对于系统而言,除非是那种安全性要求非常高的公司或者经常会有第三方安全机构对其漏洞扫描的才容易涉及到系统的内核升级,比如之前呆过一个公司,因为需要做三级等保的原因,就会涉及到系统扫描,这时 ...

  2. Python中字符的编码与解码

    1 文本和字节序列 我们都知道字符串,就是由一些字符组成的序列构成串,那么字符又是什么呢?计算机只能识别二进制的东西,那么计算机又为什么会显示我们的汉字,或者是某个字母呢? 由于最早发明使用计算机是美 ...

  3. 15个Python面试问题

    引言 想找一份Python开发工作吗?那你很可能得证明自己知道如何使用Python.下面这些问题涉及了与Python相关的许多技能,问题的关注点主要是语言本身,不是某个特定的包或模块.每一个问题都可以 ...

  4. python web框架Flask——csrf攻击

    CSRF是什么? (Cross Site Request Forgery, 跨站域请求伪造)是一种网络的攻击方式,它在 2007 年曾被列为互联网 20 大安全隐患之一,也被称为“One Click ...

  5. IOS中的深拷贝和浅拷贝

    标签: 什么是深拷贝?什么是浅拷贝? 为什么经常看到字符串属性要这样定义,那个copy是神马意思? @property(nonatomic,copy)NSString* name; 为什么下面的写法是 ...

  6. curl smtp libcurl 邮件功能使用

    /* * For an SMTP example using the multi interface please see smtp-multi.c. */ /* The libcurl option ...

  7. Vue实战狗尾草博客后台管理系统第七章

    Vue实战狗尾草博客后台管理平台第七章 本章内容为借助模块化来阐述Vuex的进阶使用. 在复杂项目的架构中,对于数据的处理是一个非常头疼的问题.处理不当,不仅对维护增加相当的工作负担,也给开发增加巨大 ...

  8. oracle自定义存储过程:删除表(无论表是否存在)和检测表是否存在

    oracle删除表,如果表不存在,就报错,在跑大型脚本(脚本长且耗时的时候)比较麻烦,一般希望的是点开始然后脚本运行到结束,不可能一直盯着屏幕等弹出提示手工点掉,mysql就很好有drop table ...

  9. eclipse C++ 配置自动提示

    转:http://www.cnblogs.com/myitm/archive/2010/12/17/1909194.html 定位到:Windows→Preferences→Java→Editor→C ...

  10. Shell命令-用户用户组管理之userdel、groupadd

    文件及内容处理 - userdel.groupadd 1. userdel:删除用户 userdel命令的功能说明 userdel 命令用于删除用户帐号.userdel 可删除用户帐号与相关的文件.若 ...