C++ 离散与组合数学之多重集合

1. 前言

数论是计算机学科的基础,将以一系列文章讨论组合数学中的一些概念,包括多重集合、等价类、多重集上的排列、错排列、圆排列、鸽巢原理、二项式定理、容斥原理、卡特兰数。

本文主要是讨论集合以及多重集合的概念以及多重集合上的排列问题。集合概念为研究群体事物提供了强有力的理论基础。

2. 集合

在理解集合之前,先理解集合中的元素概念。

元素是为研究对象提供的统一抽象名称。如具体的自然数、无理数、整数……都可称为元素。把一些元素组成的群体称为集合(简称为集),集合通常用大写的拉丁字母A,B,C,…表示,是由一些元素组成的整体。集合中的元素总是存在某种内在的关联特征。

元素与集合的关系

属于关系

a属于集合A,表述为a是集合A的元素,记作a∈A。如A={1,2,3,4} 其中 1∈A

不属于关系

a不属于集合A,表述为a不是集合A的元素,记作a∉A。例如 A={1, 2,3,4} 其中 5∉A

元素与集合的性质

  1. 确定性 :给定一个集合,任给一个元素,该元素属于或者不属于该集合,二者必居其一,不可能出现模棱两可的情况。如15之间的整数构成的集合,即是{1,2,3,4,5}。这个集合满足集合元素的确定性。

    而长的漂亮的人是不确定元素,没有任何一个标准构建这样的集合。

  2. 互异性: 一个集合中,每一个元素只能出现一次。

  3. 无序性: 一个集合中,每个元素的地位都是相同的,元素之间是无序的。{2,3}{3,2}是同一个集合。

集合的基数

一个集合中有多少元素,称为集合的基数(Cardinal)

有限集合

有限集合,如 A= {1,2,3,4} 基数就是该集合元素的个数, 记作:|A| = 4

无限集合

由无限个元素组成的集合,称为无限集合。例如 A={整数}

集合与集合的关系

  • 子集:如果集合A中的任意一个元素都在集合B中,那么集合A被称为集合B的子集。如果集合B中的每个元素都是集合A中的元素,那么集合B被称为集合A的真子集。特别的,空集包含于任何一个集合,因此空集是任何集合的子集。

  • 相等:如果两个集合A和B中的元素完全相同,并且与元素的排列顺序无关,那么这两个集合被称为相等。记作A = B。

  • 并集:由所有属于集合A或属于集合B的元素构成的集合,称为A和B的并集。记作A ∪ B。

  • 交集:由所有同时属于集合A和B的元素构成的集合,称为A和B的交集。记作A ∩ B。

  • 差集:由所有属于集合A而不属于集合B的元素构成的集合,称为A和B的差集。记作A - B。

  • 补集:由所有不属于集合A的元素构成的集合,称为集合A的补集。

3. 多重集合

多重集或多重集合是数论中的一个概念。在一个集合中,相同的元素只能出现一次,C++中称为set。因此元素仅存在有(true)或无(false)的属性。多重集(C++中称multiset)中,同一个元素可以出现多次。

多重集中出现多次的元素需要按出现的次数计算,不能只算一次。一个元素在多重集里出现的次数称为这个元素在多重集里面的重数(或重次重复度)。

如:{1,2,3}是一个集合,而{1,1,1,2,2,3}是一个多重集。其中元素1的重数是3,2的重数是2,3的重数是1。多重集{1,1,1,2,2,3}的元素个数是6。有时为了和一般的集合相区别,多重集合会用方括号而不是花括号标记,比如{1,1,1,2,2,3}会被记为[1,1,1,2,2,3]。和多元组或数组的概念不同,多重集中的元素是没有顺序分别的,也就是说{1,1,1,2,2,3}和{1,1,2,1,2,3}是同一个多重集。

3.1 C++ 中的multiset

multiset常用API

  • insert:在集合中插入元素。

函数原型:

iterator insert( const_iterator hint, const value_type& value );
template< class InputIt >
void insert( InputIt first, InputIt last );
iterator insert( const value_type& value );

函数说明:

● 重载 1:在迭代器pos前插入val,并返回一个指向该元素的迭代器;

● 重载 2:将迭代器start开始到end结束返回内的元素插入到集合中;

● 重载 3:在当前集合中插入val元素,并返回指向该元素的迭代器和一个布尔值来说明val是否成功的被插入了。

编码实现:

#include <bits/stdc++.h>
using namespace std;
int main(int argc, char** argv) {
	multiset<int> ms;
	//直接插入元素
	multiset<int>::iterator p= ms.insert(5);
	if(p!=ms.end())cout<<"插入成功"<<endl;
	else cout<<"插入失败"<<endl;
	//重复插入
	p= ms.insert(5);
	p= ms.insert(6);
	p= ms.insert(6);
	//统计 5 出现次数
	int count=ms.count(5);
	//集合中无素个数
	cout<<ms.size()<<endl;
	cout<<5<<"出现次数:"<<count<<endl;
	//使用迭代器插入
	multiset<int>::iterator begin=ms.begin();
	p=ms.insert(begin,7);
	cout<<*p<<endl;
	cout<<"迭代集合"<<endl;
	begin=ms.begin();
	multiset<int>::iterator end=ms.end();
	while(begin!=end) {
		cout<<*begin<<endl;
		begin++;
	}
	cout<<"插入另一个集合中元素"<<endl;
	multiset<int> ms_;
	ms_.insert(p,ms.end());
	cout<<"ms_元素个数:"<<ms_.size()<<endl;
	return 0;
}

3.2 多重集上的排列

多重集的全排列

所谓全排列,指从多重集合中选择所有元素,所能组成的所有排列。如有多重集:s={a1*a1,n2*a2……nk*ak} a1,a2,a3,……ak表示元素。n1,n2,……nk每个元素出现的次数。ni可能是0,也可能是正无穷大。

现有s={2,2,3,3},全排列指选择所有元素即4个元素所能组成的排列。

  • 因为是由4个数字所成的数字,排列结果一定是4位数字。

2.png

  • 先从多重集合中拿出数字2。因在多重集合中有2个,即需要在4位数字中选择2个空位置填入数字2。如下图所示,能填入2的所有可能。因元素相同,其本质是从4个位置中选择2个位置的组合数量。即C(4,2)=6

3.png

  • 再从多重集合中拿出数字3,也是有2个。因在4位数字中已经填入了22,其剩余空位置为4-2=2。即23只能填在剩下的2个位置。即C(2,2)= 1

4.png

  • 根据乘法原理,对于多重集合s={2,2,3,3}的全排列数:C(4,2)*C(2,2)=4!/2!2!

由上推导过程可知。多重集的全排列数是元素总数的阶乘除以所有元素的重复度的阶乘。其中n=n1+n2+n3……nk

1.png

如果遇到求多重集的全排列问题时,可直接套用公式。

如求多重集合S={4*2,2*6,1*7,3*4}的全排列。

  • 先求多重集合中元素的个数:n=4+2+1+3=10
  • 套用公式:res=10!/4!*2!*1!*3!=12600

多重集的非全排列

所有元素的重复度大于排列数:如s={4*2,4*3,5*4,4*6}。从集合中选择r=4个数字的非全排列数。注意,这里的排列数4小于、等于集合中重复度最小的数。

5.png

对于排列中的每一个位置都有k(为集合中元素的个数)种选择。

6.png

根据乘法原理,总排列数k*k*k*=kr

某些元素重复度小于排列数

如果有一个元素的重复度小于选取个数 ,如 S = { 3*a,2*b,1*c}多重集的三排列 , 可以使用包含排斥原理 、生成函数进行计算 ;

4. 容斥原理

容斥原理的目的:计数时,使重复的元素不被计算在内。

容斥流程:

先不考虑重叠的情况,把包含于某要求的所有元素的数目先计算出来,然后再把计数时重复计算的数目排斥出去,使得计算的结果既无遗 漏又无重复。

两个集合的容斥实现

如有A、B两个有限集合。则,|A U B|=|A|+|B|-|A ∩ B|。用韦恩图表示:

Tips: |A|表示集合A的长度。

7.png

例1:期末考试,某班有15人数学满分,有12人语文满分,并且4人语文、数学都满分,那么这个班只要有一课为满分的同学有多少人?

用数学为满分的同学构建集合A、语文为满分的同学构建集合B。如果两个集合没有交集,则班上只要有一课为满分的同学人数为15+12=27

因为同时语文、数学为满分的人数为4,说明A、B有交集,需要在两个集合总数的基础上再减去相交的共同部分,即27-4=23人。

套用容斥公式,|A ∪ B| = |A| + |B| - |A ∩ B|=15 + 12 - 4 =23

多个集合的容斥实现

如有A、B、C有限集合。则|AUBUC|=|A|+|B|+|C|-|A∩B|-|B∩C|-|A∩C|+|A∩B∩C|

8.png

例2:期末考试,某班有15人数学满分,有12人语文满分,有14人英语满分,其中4人语文、数学都满分、3人语文、英语都满分、2人英语、数学都满分。其中有3人三课全部满分,请问,班上只有有一课为满分的人数为多少?

A表示数学为满分的学生集合、用B表示语文为满分的学生集合、用C表英语为满分的学生集合。

9.png

套用公式:15+12+14-4-3-2+3=35

5. 总结

集合是离散与组合数学中重要概念。计算机的穷举思维建立在集合以及对集合的排列组合基础之上。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mfbz.cn/a/470027.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

开发微信小程序被鹅厂背刺

最近在开发微信小程序&#xff0c;没来得及更文。等开发完成后&#xff0c;给大家写保姆帖系列。刚刚看到一张动图&#xff0c;忍不住分享给大家。属实反映了鹅厂风格了。

文件上传基础篇

文件上传基础篇 文件上传漏洞原理 ​ 目标网站存在文件上传接口&#xff0c;但是对用户上传的文件没有做仔细甄别&#xff0c;导致黑客可以根据此功能点直接上传木马到网站服务器&#xff0c;造成危害 文件上传存在点 ​ 通常有头像上传&#xff0c;pdf上传 文件上传防护 …

Word为图表设置图注并在图表清单中自动生成

1如果需要自动插入题注&#xff0c;请不要自己为文件增加新的标题样式或删除自带的标题1样式 2章节大标题最好是标题1&#xff0c;2,3而不要设置标题一、二、三&#xff0c;否则图例在自动生成时会显示 图一 -1&#xff0c;调整起来会非常不方便 若实在要使用大写中文标题&…

【隐私计算实训营-001数据可信流通,从运维信任到技术信任】

1. 数据可信流通体系 信任的基石&#xff1a; 身份的可确认利益可依赖能力有预期行为有后果 2.内循环——>外循环 内循环&#xff1a;数据持有方在自己的运维安全域内队自己的数据使用和安全拥有全责。 外循环&#xff1a;数据要素在离开持有方安全域后&#xff0c;持有方…

FX-数组的使用

1一维数组 1.1一维数组的创建和初始化 1.1.1数组的创建 //代码1 int arr1[10]; char arr2[10]; float arr3[1]; double arr4[20]; //代码2 //用宏定义的方式 #define X 3 int arr5[X]; //代码3 //错误使用 int count 10; int arr6[count];//数组时候可以正常创建&#xff1…

【Linux】进程排队的理解进程状态的表述僵尸进程和孤儿进程的理解

一、进程排队的理解 进程不是一直运行的&#xff0c;进程可能会在等待某种软硬件资源。即使把进程加载到CPU中&#xff0c;也不是一直会运行的。而进程排队&#xff0c;一定是在等待某种软硬件资源&#xff08;可以是CPU&#xff0c;键盘&#xff0c;磁盘&#xff0c;网卡等等设…

Android Studio实现内容丰富的安卓图书馆座位图书预约系统

获取源码请点击文章末尾QQ名片联系&#xff0c;源码不免费&#xff0c;尊重创作&#xff0c;尊重劳动 项目编号109 1.开发环境android stuido jdk1.8 eclipse mysql tomcat 2.功能介绍 安卓端&#xff1a; 1.注册登录 2.查看公告 3.查看图书馆座位 4.查看图书馆图书&#xff0c…

k8s详细教程

Kubernetes详细教程 1. Kubernetes介绍 1.1 应用部署方式演变 在部署应用程序的方式上&#xff0c;主要经历了三个时代&#xff1a; 传统部署&#xff1a;互联网早期&#xff0c;会直接将应用程序部署在物理机上 优点&#xff1a;简单&#xff0c;不需要其它技术的参与 缺点…

《1w实盘and大盘基金预测 day7》

昨日预测有点差劲&#xff0c;最低点也相差五个点。 打分C 公众号&#xff1a;JavaHelmet 昨天预测&#xff1a; 3052-3062-3076-3115 3067是趋势线&#xff0c;有回踩需求 5-30-60分钟级别顶钝 大盘冲到标红的点位3115或者3100就需注意。不要随意追高&#xff08;最高309…

第四百一十一回

文章目录 1. 概念介绍2. 思路与方法2.1 实现思路2.2 实现方法 3. 示例代码4. 内容总结 我们在上一章回中介绍了"给geolocator插件提交问题的结果"相关的内容&#xff0c;本章回中将介绍自定义标题栏.闲话休提&#xff0c;让我们一起Talk Flutter吧。 1. 概念介绍 我…

蓝桥杯备赛_python_DFS搜索算法_刷题学习笔记

1.是什么 沿着一条路径一直搜索下去&#xff0c;在无法搜索时&#xff0c;回退到刚刚访问过的节点。并且每个节点只能访问一次。本质上是持续搜索&#xff0c;遍历了所有可能的情况&#xff0c;必然能得到解。 流程是一个树的形式&#xff0c;每次一条路走到黑。 目的主要是达到…

哈尔滨工业大学 《材料物理》 笔记-3

原内容请参考哈尔滨工业大学何飞教授&#xff1a;https://www.bilibili.com/video/BV18b4y1Y7wd/?p12&spm_id_frompageDriver&vd_source61654d4a6e8d7941436149dd99026962 或《材料物理性能及其在材料研究中的应用》&#xff08;哈尔滨工业大学出版社&#xff09; 量…

杨氏矩阵的查找(复杂度<O(N))

题目&#xff1a; 解释&#xff1a;时间复杂度小于O(N)即不要一个一个的去遍历查找。 思路&#xff1a; 一个33的二维数组如图所示&#xff1a; 一&#xff1a;先找到一个最关键的数字&#xff0c;3&#xff08;下标为0,2&#xff09; 关键数的关键之处在于&#xff08;处于…

【Unity】从0到1的横版2d制作笔记-DAY1

写在前面&#xff1a; 感谢旻子提供的Unity2d课程捏&#xff0c;红豆泥阿里嘎多 创建项目 测试Visual Studio的使用 右键选择【create】&#xff0c;右键创建C# Script&#xff0c;待文件创建完毕后双击查看能否正确跳转。 正确跳转的结果是能看见代码中注释标注有&#xff1a;…

15届蓝桥杯第二期模拟赛所有题目解析

文章目录 &#x1f9e1;&#x1f9e1;t1_求余&#x1f9e1;&#x1f9e1;思路代码 &#x1f9e1;&#x1f9e1;t2_灌水&#x1f9e1;&#x1f9e1;思路代码 &#x1f9e1;&#x1f9e1;t3_字符显示&#x1f9e1;&#x1f9e1;思路代码 &#x1f9e1;&#x1f9e1;t4_区间最大和…

(56)删除每行中的最大值

文章目录 1. 每日一言2. 题目3. 解题思路4. 代码5. 结语 1. 每日一言 抱怨过去发生的一切&#xff0c;就等于丧失了力量&#xff0c;白白浪费了往事要带给我们的成长。 2. 题目 题目链接&#xff1a;删除每行中的最大值 给你一个 m x n 大小的矩阵 grid &#xff0c;由若干正…

线程工具类与原子类

参考文档&#xff1a; CountDownLatch、CyclicBarrier、Semaphore的用法和区别juc15_基本AtomicInteger、数组、引用AtomicStampedReference、对象的属性修改原子类 AtomicIntegerFieldUp 、原子操作增强类LongAdder 辅助工具类 CountDownLatch(闭锁) 做减法 允许一个或多个…

c语言文件操作(2)

1.文件的随机读写&#xff1a; fseek函数 int fseek ( FILE * stream, long int offset, int origin ); fseek函数是根据文件指针的位置和偏移量来定位文件指针。 其中&#xff0c;origin所含的参数&#xff1a; seek_set&#xff1a;文件开头 seek_cur&#xff1a;文件指…

DFS-重复覆盖模型

糖果 1243. 糖果 - AcWing题库 首先是最暴力的做法&#xff0c;我们枚举所有的选法&#xff0c;当某种选法可以尝到所有口味的糖果时&#xff0c;比较当前购买的糖果数和当前的res&#xff0c;迭代出res的最小值。这样进行搜索的话&#xff0c;最极端的状态下树的深度是n&…

腾讯云服务器多少钱1个月?2024一个月收费阿济格IE吧

2024腾讯云服务器多少钱一个月&#xff1f;5元1个月起&#xff0c;腾讯云轻量服务器4核16G12M带宽32元1个月、96元3个月&#xff0c;8核32G22M配置115元一个月、345元3个月&#xff0c;腾讯云轻量应用服务器61元一年折合5元一个月、4核8G12M配置646元15个月、2核4G5M服务器165元…