Devu和鲜花 (容斥原理)
时间:2019-08-06
本文章向大家介绍Devu和鲜花 (容斥原理),主要包括Devu和鲜花 (容斥原理)使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。
题目:
Devu有N个盒子,第i个盒子中有AiAi枝花。
同一个盒子内的花颜色相同,不同盒子内的花颜色不同。
Devu要从这些盒子中选出M枝花组成一束,求共有多少种方案。
若两束花每种颜色的花的数量都相同,则认为这两束花是相同的方案。
结果需对109+7109+7取模之后方可输出。
输入格式
第一行包含两个整数N和M。
第二行包含N个空格隔开的整数,表示A1,A2,…,ANA1,A2,…,AN。
输出格式
输出一个整数,表示方案数量对109+7109+7取模后的结果。
数据范围
1≤N≤201≤N≤20,
0≤M≤10140≤M≤1014,
0≤Ai≤10120≤Ai≤1012
输入样例:
3 5
1 3 2
输出样例:
3
解题报告:
一开始没有研究出来怎么容斥处理,后来参考了一下大佬的博客,才理解了这道题目的真谛!
首先假设如果所有的fifi都没有限制的情况。
根据无限多重集合的组合数那么答案即为C(s,n+s−1)
我们需要从这个答案中减去不合法的情况。
不合法的情况即为xi>fixi>fi的情况。
设AiAi为xi>fixi>fi的方案。
|Ai|=C(s−(fi+1),n+s−1−(fi+1))
相当于我们预先放好这fi+1fi+1个元素。
同理|Ai⋂Aj|=C(s−(fi+1)−(fj+1),n+s−1−(fi+1)−(fj+1))
根据容斥原理答案即为
C(s,n+s−1)−∑1≤i≤n|Ai|+∑1≤i<j≤n|Ai⋂Aj|−...(省略)
我们可以通过状态压缩表示每个状态。
预处理每个状态需要预先放好几个元素。
最后一遍扫描来统计答案。
时间复杂度O(2nn)
ac代码:
1 #include<bits/stdc++.h> 2 using namespace std; 3 typedef long long ll; 4 5 const int mod=1e9+7; 6 int n,lim; 7 ll s,ans; 8 ll f[30],inv[30],sum[1100000]; 9 int num[1100000]; 10 ll comb(ll n,ll m) 11 {//求解C(n,m) 12 if(m<0) 13 return 0; 14 ll ret=1; 15 for(ll i=m+1;i<=n;i++) 16 ret=ret*(i%mod)%mod;//n!/m! 17 for(int i=1;i<=n-m;i++) 18 ret=ret*inv[i]%mod;//(n-m)! 19 return ret; 20 } 21 22 int main() 23 { 24 cin>>n>>s;//n个盒子,挑选s朵花 25 for(int i=0;i<n;i++) 26 cin>>f[i];//输入n个盒子中的花朵数目 27 inv[1]=1; 28 for(int i=2;i<=n+1;i++) 29 inv[i]=(inv[mod%i]*(mod-mod/i))%mod;//神奇的求解逆元打表 30 lim=(1<<n)-1;//二进制枚举 ,便于容斥 31 for(int i=0;i<=lim;i++) 32 { 33 for(int j=0;j<n;j++) 34 { 35 if(i&(1<<j)) 36 { 37 sum[i]+=f[j]+1;// 预先放好fi+1个元素 38 num[i]++;//标记一下出现的次数 39 } 40 } 41 }//已经处理好了所有的状态,从1,2,--> n 42 for(int i=0;i<=lim;i++) 43 { 44 if(num[i]%2) 45 ans=(ans-comb(s+n-1-sum[i],s-sum[i])+mod)%mod; 46 else 47 ans=(ans+comb(s+n-1-sum[i],s-sum[i]))%mod; 48 } 49 cout<<ans<<endl; 50 }
原文地址:https://www.cnblogs.com/Spring-Onion/p/11310470.html
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法