1. 问题描述:

Devu 有 N 个盒子,第 i 个盒子中有 Ai 枝花。同一个盒子内的花颜色相同,不同盒子内的花颜色不同。Devu 要从这些盒子中选出 M 枝花组成一束,求共有多少种方案。若两束花每种颜色的花的数量都相同,则认为这两束花是相同的方案。结果需对 10 ^ 9 + 7 取模之后方可输出。

输入格式

第一行包含两个整数 N 和 M。第二行包含 N 个空格隔开的整数,表示 A1,A2,…,AN。

输出格式

输出一个整数,表示方案数量对 10 ^ 9 + 7 取模后的结果。

数据范围

1 ≤ N ≤ 20,
0 ≤ M ≤ 10 ^ 14,
0 ≤ Ai ≤ 10 ^ 12

输入样例:

3 5
1 3 2

输出样例:

3
来源:https://www.acwing.com/problem/content/216/

2. 思路分析:

这道题目属于容斥原理中一道很经典的题目,我们先考虑一下理想的情况,每个盒子中的花有无限个,我们需要求解出N个盒子中选择M朵花的方案数目,这个与不定方程中正整数解得题目是一样的,我们先可以做一下映射,令yi = xi + 1,这样yi >= 1,相当于是给我们N + M个小球,有N + M - 1个空隙,N - 1个隔板,求解总共的方案数目,使用隔板法我们知道最终的方案数目为CN+M-1N-1

而原问题是有限制的,x1 <= A1,x2 <= A2,...xN <= AN,怎么样通过没有限制的情况拼凑出有限制的情况呢?这个时候就需要使用到容斥原理了,正向求解不好求解那么就反向求解,我们可以使用没有限制条件下总的方案数目减去不满足条件的方案数目那么就是答案了:

3. 代码如下:

class Solution:# 快速幂def quickPower(self, a: int, b: int, p: int):res = 1while b > 0:if b & 1:res = res * a % pa = a * a % pb >>= 1return res# 使用公式计算组合数def C(self, a: int, b: int, mod: int, down: int):if a < b: return 0up = 1for i in range(a, a - b, -1):up = i % mod * up % modreturn up * down % moddef process(self):# n个盒子, 总共要选出m枝花n, m = map(int, input().split())# A存储每一个盒子中花的数量A = list(map(int, input().split()))res, mod = 0, 10 ** 9 + 7down = 1for i in range(1, n):down = down * i % mod# 先预处理出down!的阶乘, 而且down!远小于mod所以可以使用费马小定理求解出逆元down = self.quickPower(down, mod - 2, mod)# 枚举2 ^ n个状态, 计算其中1的数目for i in range(1 << n):a, b = m + n - 1, n - 1# 容斥原理中奇数项是负数, 偶数项是整数, 所以在枚举二进制状态的时候计算出1的数目那么就是最终的符号sign = 1for j in range(n):if i >> j & 1:sign *= -1# 减去对应的1的数目a -= A[j] + 1res = (res + self.C(a, b, mod, down) * sign) % modreturn resif __name__ == "__main__":print(Solution().process())

214 Devu和鲜花(容斥原理,隔板法)相关推荐

  1. 算法竞赛——进阶指南——acwing214. Devu和鲜花 容斥原理

    多重集组合数一般形式. 用二进制处理更加方便 #include <bits/stdc++.h> using namespace std; typedef long long ll; #de ...

  2. 排列组合---隔板法

    1.定义 隔板法就是在n个元素间插入(b-1)个板,即把n个元素分成b组的方法.C(n-1,b-1) 2.条件 隔板法必须满足三个条件: (1)这n个元素必须相同,(2)所分成的每一组至少分得一个元素 ...

  3. sql相同顺序法和一次封锁法_数学专题 | Ep01 隔板法的妙用

    数学专题(一)  隔板法的妙用 浓度常见哪些问题? 排列组合分堆?涂色?到底掌握透彻了吗? 解析几何与韦达定理? 公式总是记不住?应用题还不会解? 除了写作(写作听我的).逻辑(逻辑说)专题外,本周起 ...

  4. 排列组合中关于捆绑法、插空法、插隔板法

    捆绑法:当要求某几个元素必须相邻(挨着)时,先将这几个元素看做一个整体,(比如:原来3个元素,整体考虑之后看成1个元素)然后将这个整体和其它元素进行考虑.这时要注意:一般整体内部各元素如果在前后顺序上 ...

  5. 4002 构造数组(可重复组合数问题--隔板法)

    1. 问题描述: 现在需要构造一对数组 (a,b),要求: 数组 a 和数组 b 的长度都为 m: 两个数组中的元素的取值范围都是 [1,n]: ∀i∈[1,m],ai ≤ bi: 数组 a 中元素非 ...

  6. 组合数学之隔板法:多元一次方程组解的统计

    1. 内容 讨论多元一次不定方程: x 1 + x 2 + . . . + x d = t x_1 + x_2 + ... + x_d = t x1​+x2​+...+xd​=t有解的情况 隔板法求解 ...

  7. 后缀数组+贪心+隔板法

    题意:给你sa数组,就是每个排名的后缀开始下标,让你求有多少种满足要求的串,有那么一个原理,对于相邻排名的两个后缀,后缀i的首字母要不要大于i-1,的取决于,第二个字符的比较,如果i的第二个字符> ...

  8. 排列组合的简单应用(隔板法)

    高中数学的排列组合,在许多题目中也有应用.甚至可以达到更快的解题速度,同时也会减少时间复杂度. 一般应用 拿NYOJ的一道题为例.https://acm.nyist.edu.cn/p/210. 通过读 ...

  9. 高中数学基础05:排列、组合以及隔板法

    内容来自百度百科知识以及东方耀老师笔记内容的整合 1.排列组合基本概述 排列组合是组合学最基本的概念.所谓排列,就是指从给定个数的元素中取出指定个数的元素进行排序.组合则是指从给定个数的元素中仅仅取出 ...

最新文章

  1. ResultSet获取set中的记录数
  2. CyclicBarrier和CountDownLatch区别
  3. linux 密码记录文件 .netrc 简介
  4. sigaction函数学习
  5. 【Java并发性和多线程】线程安全及不可变性
  6. codeup 2044 暴力搜索
  7. Linux 下压缩与解压.zip 和 .rar
  8. ST众泰:未与长城汽车签署过任何战略协议
  9. 牛客网NOIP赛前集训营 提高组 第5场 T2 旅游
  10. elk怎么读的_大数据采集和抽取怎么做?这篇文章终于说明白了!
  11. 确定性钱包的多账户层次结构(bitcoinj使用BIP44)
  12. POI dataFormat种类
  13. LM2596数控电路原理分析
  14. Qt Creator编辑3D场景
  15. [LuoguP3503]「BZOJ2086」[POI2010] Blocks
  16. SLAM中的边缘化舒尔补
  17. 计算机科学学院凤凰院徽,数学科学学院院徽、院训展示
  18. 新一代视频压缩技术 H.265 解析
  19. HTML静态网页作业——我的家乡安庆
  20. clickhouse分布式表调研

热门文章

  1. js逗号分割数组和数组分割成字符串
  2. 计算机上删除c$共享,IPC$、ADMIN$、C$、D$都是什么?如何关闭取消删除Windows默认共享...
  3. W3C?什么是W3C相关标准?
  4. 什么你还不知道招聘信息,小唐来教你——最新2021爬取拉勾网招聘信息(二)
  5. 股票日内交易策(源码)
  6. MySQL使用什么关键字添加唯一约束_MySQL使用____关键字添加唯一约束。
  7. Python爬虫常用的爬虫注意事项及技巧
  8. Word基础(七)文字添加拼音
  9. 一度智信 | 教你拼多多主图的制作
  10. 荷花与美人【 注:诗画皆为 AI 所作】