《趣题学算法》—第1章1.3节加法原理和乘法原理

简介:

本节书摘来自异步社区《趣题学算法》一书中的第1章1.3节加法原理和乘法原理,作者徐子珊,更多章节内容可以访问云栖社区“异步社区”公众号查看。

1.3 加法原理和乘法原理
组合数学中有两条著名的原理——加法原理和乘法原理。利用这两条原理可以快速地解决一些计数问题。

加法原理:做一件事,完成它可以有n类办法,在第一类办法中有m1种不同的方法,在第二类办法中有m2种不同的方法,……,在第n类办法中有mn种不同的方法,那么完成这件事共有N=m1+m2+m3+…+mn种不同方法。

乘法原理:做一件事,完成它需要分成n个步骤,做第一步有m1种不同的方法,做第二步有m2种不同的方法,……,做第n步有mn种不同的方法,那么完成这件事共有N=m1×m2×m3×…×mn种不同的方法。
维基百科


c3d6ab8969bc85ed4ccf3a64f420bb9a670d53ef

问题描述
冒泡排序是一种简单的排序算法。该算法反复扫描欲排序的列表,比较相邻元素对,若两者顺序不对,就将它们交换。这样对列表的扫描反复进行直至列表中不存在需要交换的元素为止,这意味着列表已经排好序。算法之所以叫此名字,是缘于最小的元素就像“泡泡”一样冒到列表的顶端,这是一种基于比较的排序算法。

冒泡排序是一种非常简单的排序算法,其运行时间为O(n2)。每趟操作从列表首开始,以此比较相邻项,需要时交换两者。重复进行若干趟这样的操作直至无需再做任何交换操作为止。假定恰好做了T趟操作,序列就按升序排列,我们就说T为对此序列的冒泡排序趟数。下面是一个例子。序列为“5 1 4 2 8”,对其施行的冒泡排序如下所示。

第一趟操作:

( 51 4 2 8 ) −> ( 1 5 4 2 8 ),比较头两个元素,并将其交换。

( 1 5 4 2 8 ) −> ( 1 4 5 2 8 ),交换,因为5 > 4。

( 1 4 5 2 8 ) −> ( 1 4 2 5 8 ),交换,因为5 > 2。

( 1 4 2 5 8 ) −> ( 1 4 2 5 8 )由于这两个元素已经保持顺序(8>5),算法不对它们进行交换。

第二趟操作:

( 1 4 2 5 8 ) −> ( 1 4 2 5 8 )

( 1 4 2 5 8 ) −> ( 1 2 4 5 8 ),交换,因为4 > 2。

( 1 2 4 5 8 ) −> ( 1 2 4 5 8 )

( 1 2 4 5 8 ) −> ( 1 2 4 5 8 )

在T = 2趟后,序列已经排好序,所以我们说对此序列冒泡排序的趟数为2。

ZX在算法课中学习冒泡排序,他的老师给他留了一个作业。老师给了ZX一个具有N个两两不等的元素的数组A,并且已经排成升序。老师告诉ZX,该数组是经过了K趟的冒泡排序得来的。问题是:A有多少种初始状态,使得对其进行冒泡排序,趟数恰为K?结果可能是一个很大的数值,你只需输出该数相对于模20100713的剩余。

输入

输入包含若干个测试案例。

第一行含有一个表示案例数的整数T (Tleqslant100 000)。

跟着的是T行表示各案例的数据。每行包含两个整数N和K(1leqslantNleqslant1,000,000, 0leqslantKleqslantN−1),其中N表示序列长度而K表示对序列进行冒泡排序的趟数。

输出

对每个案例,输出序列的初始情形数对模20100713的剩余,每个一行。

输入样例

3
3 0
3 1
3 2

输出样例

1
3
2

解题思路

(1)数据的输入与输出

根据输入文件格式的描述,首先在其中读出测试案例个数T。然后依次读取案例数据N和K。对每个案例计算进行K趟处理就能实现冒泡排序的数组A[1..N]有多少种可能的初始状态,并将所得结果作为一行写入输出文件。

1 打开输入文件inputdata
2 创建输出文件outputdata
3 从inputdata中读取案例数T
4 for t←1 to T
5   do 从inputdata中读取案例数据N, K
6      BUBLLE-SORT-ROUNDS(N, K, k, x, count)
7      将count作为一行写入outputdata中
8 关闭inputdata
9 关闭outpudata

其中,第6行调用过程BUBLLE-SORT-ROUNDS(N, K, k, x, count)计算进行K趟处理就能实现冒泡排序的数组A[1..N]有多少种可能的初始状态,是解决一个案例的关键。

(2)处理一个案例的算法过程

为方便计,我们假定序列A中的N个数为0,1,…,N-1。注意,冒泡排序的第k趟操作,总是将当前范围(A[0..k−1])内的最大的元素推至当前范围的最后位置A[k−1]。

除了针对趟数K=0的唯一初始状态A[0..N−1]已经有序外,我们归纳K=k(1leqslantk

K=1时,初始状态只能是1,…, N−1中的一个元素不出现在自己应有的位置上,而其他元素均处于相对顺序的位置上。对于1而言,它要出现在A[0]处;对于2而言,它可以出现在A[0]、A[1]处之一;…一般地,对于i(0

K=2时,初始状态可以是1,…, N−1中的两个元素不出现在应有的位置上,而其他元素均处于相对顺序的位置上。对于0

一般地,K=k(1leqslantk

若将1~N-1中的K个数0

**BUBLLE-SORT-ROUNDS(N, K, k, x, count) ▷k表示递归层次
1 if kgeqslantK ▷得到一个积
2 then item←1
3 for i←1 to K
4 do item←(itemxi) MOD 20100713
5 count←(count+item) MOD 20100713
6 return
7 if k=0
8 then begin←N-1, end← K ▷顶层,x[0]的取值范围
9 else begin←xk-1-1, end← K-k ▷k>1时,x[k]的取值范围
10 for p←begin downto end ▷确定第k个因子
11 do xk ← p
12 BUBLLE-SORT-ROUNDS(N, K, k+1)**
算法1-10 计算具有N个不同元素恰做K趟操作完成排序的序列初始状态数的过程

对测试案例数据N和K,上述过程运行如下。这是一个递归过程。递归层次由参数k表示,表示计算一个积中第k个因子。最顶层的调用应该是BUBLLE-SORT-ROUNDS(N, K, 0, x, count),即k=0。

第1~7行当检测到k>K时,意味着得到一个积的所有因子。由于20100713是一个素数,以它为模的剩余类[3]对加法和乘法运算是封闭的,所以,可以对每一步乘法运算求关于模20100713的剩余,也可以在将积累加到count时进行求关于模20100713的剩余。

第7~8行if-then-else结构针对k是否为1决定第k个因子的取值范围begin~end。

第9~12行的for循环完成对第k个因子xk的确定后,调用自身确定xk+1。

由于sum{_{1<{{i}_{1}}

解决本问题的算法的C++实现代码存储于文件夹laboratory/Bubble Sort中,读者可打开文件BubbleSort.cpp研读,并试运行之。

相关文章
|
4月前
|
数据采集 机器学习/深度学习 算法
|
2月前
|
存储 算法 Java
解析HashSet的工作原理,揭示Set如何利用哈希算法和equals()方法确保元素唯一性,并通过示例代码展示了其“无重复”特性的具体应用
在Java中,Set接口以其独特的“无重复”特性脱颖而出。本文通过解析HashSet的工作原理,揭示Set如何利用哈希算法和equals()方法确保元素唯一性,并通过示例代码展示了其“无重复”特性的具体应用。
45 3
|
2月前
|
机器学习/深度学习 算法 机器人
多代理强化学习综述:原理、算法与挑战
多代理强化学习是强化学习的一个子领域,专注于研究在共享环境中共存的多个学习代理的行为。每个代理都受其个体奖励驱动,采取行动以推进自身利益;在某些环境中,这些利益可能与其他代理的利益相冲突,从而产生复杂的群体动态。
197 5
|
18天前
|
算法 容器
令牌桶算法原理及实现,图文详解
本文介绍令牌桶算法,一种常用的限流策略,通过恒定速率放入令牌,控制高并发场景下的流量,确保系统稳定运行。关注【mikechen的互联网架构】,10年+BAT架构经验倾囊相授。
令牌桶算法原理及实现,图文详解
|
28天前
|
负载均衡 算法 应用服务中间件
5大负载均衡算法及原理,图解易懂!
本文详细介绍负载均衡的5大核心算法:轮询、加权轮询、随机、最少连接和源地址散列,帮助你深入理解分布式架构中的关键技术。关注【mikechen的互联网架构】,10年+BAT架构经验倾囊相授。
5大负载均衡算法及原理,图解易懂!
|
2月前
|
并行计算 算法 IDE
【灵码助力Cuda算法分析】分析共享内存的矩阵乘法优化
本文介绍了如何利用通义灵码在Visual Studio 2022中对基于CUDA的共享内存矩阵乘法优化代码进行深入分析。文章从整体程序结构入手,逐步深入到线程调度、矩阵分块、循环展开等关键细节,最后通过带入具体值的方式进一步解析复杂循环逻辑,展示了通义灵码在辅助理解和优化CUDA编程中的强大功能。
|
2月前
|
算法 数据库 索引
HyperLogLog算法的原理是什么
【10月更文挑战第19天】HyperLogLog算法的原理是什么
56 1
|
2月前
|
机器学习/深度学习 人工智能 算法
[大语言模型-算法优化] 微调技术-LoRA算法原理及优化应用详解
[大语言模型-算法优化] 微调技术-LoRA算法原理及优化应用详解
82 0
[大语言模型-算法优化] 微调技术-LoRA算法原理及优化应用详解
|
2月前
|
搜索推荐 Shell
解析排序算法:十大排序方法的工作原理与性能比较
解析排序算法:十大排序方法的工作原理与性能比较
54 9
|
2月前
|
机器学习/深度学习 算法
机器学习入门(三):K近邻算法原理 | KNN算法原理
机器学习入门(三):K近邻算法原理 | KNN算法原理