【XSY3156】简单计数II 容斥 DP
题目大意
定义一个序列的权值为:把所有相邻的相同的数合并为一个集合后,所有集合的大小的乘积。
特别的,第一个数和最后一个数是相邻的。
现在你有 \(n\) 种数,第 \(i\) 种有 \(c_i\) 个。求所有不同的序列的权值的和。
\(n\leq 50,c_i\leq 100\)
题解
考虑第一个数和最后一个数不相邻时怎么做。
记 \(g_{i,j}\) 为出现了 \(i\) 次的数分成 \(j\) 个集合,所有集合大小的乘积的和。
\]
假设最后 \(i\) 分成了 \(a_i\) 个集合,那么答案就是 \(\prod_{i=1}^ng_{c_i,a_i}\) 再乘上方案数。
方案数可以容斥求。
具体来说,把最后相邻且同色的球合并成一个大球。设最后有 \(b_i\) 个大球,那么容斥系数就是 \({(-1)}^{a_i-b_i}\),带容斥系数的方案数就是 \(\binom{a_i-1}{b_i-1}{(-1)}^{a_i-b_i}\)
最后这 \(\sum b_i\) 个球可以随意放,方案数是 \(\frac{(\sum b_i)!}{\prod b_i!}\)
总的答案是
\]
这样就可以 DP 了。(状态为 \(i\) 和 \(\sum b_i\))
考虑第一个数和最后一个数相邻时怎么做。
可以用最小表示法,令第一个数为 \(1\) 且 最后一个数不为 \(1\)(除非 \(n=1\))。
只需要在后面计算组合数的时候把 \(b_1-1\) 再除以 \(a_1\) 就可以得到第一个数为 \(1\) 的方案数。
把 \(b_1-2\) 再除以 \(a_1\) 就可以得到第一个数为 \(1\) 且最后一个数也是 \(1\) 的方案数。
除以 \(a_1\) 是因为一个方案会被算多次。
再把方案数乘以 \(\sum c_i\) 就是答案了。
时间复杂度:\(O((\sum c_i)^2)\)
代码
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
typedef long long ll;
const ll p=1000000007;
ll fac[5010],ifac[5010],inv[5010];
ll f[60][5010];
ll g[110][110];
int a[60];
int n;
int s[60];
ll c[110][110];
ll c1[110],c2[110];
ll binom(int x,int y)
{
return x>=y&&y>=0?fac[x]*ifac[y]%p*ifac[x-y]%p:0;
}
int main()
{
#ifndef ONLINE_JUDGE
freopen("c.in","r",stdin);
freopen("c.out","w",stdout);
#endif
scanf("%d",&n);
for(int i=1;i<=n;i++)
{
scanf("%d",&a[i]);
s[i]=s[i-1]+a[i];
}
inv[1]=fac[0]=fac[1]=ifac[0]=ifac[1]=1;
for(int i=2;i<=5000;i++)
{
inv[i]=-p/i*inv[p%i]%p;
fac[i]=fac[i-1]*i%p;
ifac[i]=ifac[i-1]*inv[i]%p;
}
g[0][0]=1;
for(int i=1;i<=100;i++)
for(int j=1;j<=100;j++)
for(int k=1;k<=i;k++)
g[i][j]=(g[i][j]+g[i-k][j-1]*k)%p;
f[0][0]=1;
for(int i=1;i<n;i++)
for(int j=1;j<=a[i];j++)
for(int k=1;k<=j;k++)
c[i][k]=(c[i][k]+g[a[i]][j]*binom(j-1,k-1)%p*((j-k)&1?-1:1))%p;
for(int i=n;i<=n;i++)
for(int j=1;j<=a[i];j++)
for(int k=1;k<=j;k++)
c1[k]=(c1[k]+g[a[i]][j]*binom(j-1,k-1)%p*((j-k)&1?-1:1)*inv[j])%p;
for(int i=1;i<=n;i++)
for(int j=1;j<=a[i];j++)
for(int k=0;k<=s[i-1];k++)
f[i][k+j]=(f[i][k+j]+f[i-1][k]*c[i][j]%p*binom(k+j,k))%p;
ll ans=0;
for(int j=1;j<=a[n];j++)
for(int k=0;k<=s[n-1];k++)
ans=(ans+f[n-1][k]*c1[j]%p*(binom(k+j-1,k)-binom(k+j-2,k)))%p;
ans=ans*s[n]%p;
ans=(ans+p)%p;
printf("%lld\n",ans);
return 0;
}
【XSY3156】简单计数II 容斥 DP的更多相关文章
- 【BZOJ2839】集合计数(容斥,动态规划)
[BZOJ2839]集合计数(容斥,动态规划) 题面 BZOJ 权限题 Description 一个有N个元素的集合有2^N个不同子集(包含空集),现在要在这2^N个集合中取出若干集合(至少一个),使 ...
- [CF1086E]Beautiful Matrix(容斥+DP+树状数组)
给一个n*n的矩阵,保证:(1)每行都是一个排列 (2)每行每个位置和上一行对应位置不同.求这个矩阵在所有合法矩阵中字典序排第几.考虑类似数位DP的做法,枚举第几行开始不卡限制,那么显然之前的行都和题 ...
- $bzoj2560$ 串珠子 容斥+$dp$
正解:容斥+$dp$ 解题报告: 传送门$QwQ$ $umm$虽然题目蛮简练的了但还是有点难理解,,,我再抽象一点儿,就说有$n$个点,点$i$和点$j$之间有$a_{i,j}$条无向边可以连,问有多 ...
- 知识点简单总结——minmax容斥
知识点简单总结--minmax容斥 minmax容斥 好像也有个叫法叫最值反演? 就是这样的一个柿子: \[max(S) = \sum\limits_{ T \subseteq S } min(T) ...
- HDU 5794 A Simple Chess (容斥+DP+Lucas)
A Simple Chess 题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=5794 Description There is a n×m board ...
- 【BZOJ3622】已经没有什么好害怕的了 容斥+DP
[BZOJ3622]已经没有什么好害怕的了 Description Input Output Sample Input 4 2 5 35 15 45 40 20 10 30 Sample Output ...
- bzoj3782上学路线(Lucas+CRT+容斥DP+组合计数)
传送门:https://www.lydsy.com/JudgeOnline/problem.php?id=3782 有部分分的传送门:https://www.luogu.org/problemnew/ ...
- [HAOI2017]方案数[组合计数、容斥、dp]
题意 题目链接 分析 先考虑没有障碍怎么做,定义 f(i,j,k) 每一维走了 i,j,k 位的方案数,转移乘个组合数即可. 现在多了一些障碍,考虑容斥.实际我们走过的点都有严格的大小关系,所以先把所 ...
- bzoj2839 集合计数(容斥)
2839: 集合计数 Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 883 Solved: 490[Submit][Status][Discuss] ...
随机推荐
- Django 如何获取真实远程客户端IP
问题简述 我们知道HttpRequest.META字典包含所有HTTP头部信息(可用的头部信息取决于客户端和服务器).一般情况下,HttpRequest.META.get('REMOTE_ADDR') ...
- 如何用git上传代码到github详细步骤
注册账户 这个小菜鸟带着心跳写的第一篇博客! 还请大家多多提点! 想使用github,第一步肯定是要注册github账号,有了账号就是直接登录啦 可以直接打开http://github.com页面注册 ...
- mssql sqlserver 快速表备份和表还原的方法
摘要: 在sqlserver维护中,我们偶尔需要运行一些sql脚本对数据进行相关修改操作,在数据修改前我们必须对表数据进行备份来避免出现异常时,可以快速修复数据, 下文讲述sqlserver维护中,快 ...
- SQL 使用临时表和临时变量完成update表字段---实际案例
-- 使用临时表 -- 创建临时表 --ALTER TABLE TS_ExpenseApplication_Reim_Detail ADD BgCode NVARCHAR() NULL, BgItem ...
- 利用ZYNQ SOC快速打开算法验证通路(1)——MATLAB浮点数与定点二进制补码互转
最近本人一直在学习ZYNQ SOC的使用,目的是应对科研需要,做出通用的算法验证平台.大概思想是:ZYNQ PS端负责与MATLAB等上位机数据分析与可视化软件交互:既可传输数据,也能通过上位机配置更 ...
- maven常用仓库
==================2014-04-19添加========可访问=============================== http://nexus.openkoala.org/ ...
- Linux(Centos7)下搭建SVN服务器 (转载)
系统环境:centos7.2 第一步:通过yum命令安装svnserve,命令如下: yum -y install subversion 此命令会全自动安装svn服务器相关服务和依赖,安装完成会自动停 ...
- python3 shell 中添加清屏
在windows中: 安装目录 \Lib( D:\Python37\Lib) 中添加 ClearWindow.py 文件,文件内容: """ Clear Window ...
- 新数据革命: 开源C#图形化爬虫引擎Hawk5发布
https://ferventdesert.github.io/Hawk/ Hawk是一款由沙漠之鹰历时五年个人业余时间开发的,开源图形化爬虫和数据清洗工具,GitHub Star超过2k+,前几代版 ...
- Linux-基础学习(三)-Nginx学习
1.nginx安装与部署 1.1 nginx入门 Web 网络服务是一种被动访问的服务程序,即只有接收到互联网中其他主机发出的 请求后才会响应,最终用于提供服务程序的 Web 服务器会通过 HTTP( ...