信息奥赛基础知识常用算法与策略.docx
- 文档编号:26125880
- 上传时间:2023-06-17
- 格式:DOCX
- 页数:26
- 大小:55.57KB
信息奥赛基础知识常用算法与策略.docx
《信息奥赛基础知识常用算法与策略.docx》由会员分享,可在线阅读,更多相关《信息奥赛基础知识常用算法与策略.docx(26页珍藏版)》请在冰豆网上搜索。
信息奥赛基础知识常用算法与策略
信息奥赛基础知识——常用算法与策略
第一章算法
1.1什么是算法
算法是程序设计的精髓,程序设计的实质就是构造解决问题的算法,将其解释为计算机语言。
算法是在有限步骤内求解某一问题所使用的一组定义明确的规则。
通俗点说,就是计算机解题的过程。
在这个过程中,无论是形成解题思路还是编写程序,都是在实施某种算法。
前者是推理实现的算法,后者是操作实现的算法。
一个算法应该具有以下五个重要的特征:
1.有穷性:
一个算法必须保证执行有限步之后结束;
2.确切性:
算法的每一步骤必须有确切的定义;
3.输入:
一个算法有0个或多个输入,以刻画运算对象的初始情况;
4.输出:
一个算法有一个或多个输出,以反映对输入数据加工后的结果。
没有输出的算法是毫无意义的;
5.可行性:
算法原则上能够精确地运行,而且人们用笔和纸做有限次运算后即可完成。
1.2算法的表示方法
算法通常有三种表示方法:
自然语言法、程序流程图法、程序法。
结构化程序设计三种程序结构的流程图(N-S图)如下:
1.顺序结构
2.选择结构
3.循环结构
当型循环 直到型循环
例题1:
百钱买百鸡问题:
1.3算法分析
算法的复杂性
算法的复杂性是算法效率的度量,是评价算法优劣的重要依据。
一个算法的复杂性的高低体现在运行该算法所需要的计算机资源的多少上面,所需的资源越多,我们就说该算法的复杂性越高;反之,所需的资源越低,则该算法的复杂性越低。
计算机的资源,最重要的是时间和空间(即存储器)资源。
因而,算法的复杂性有时间复杂性和空间复杂性之分。
不言而喻,对于任意给定的问题,设计出复杂性尽可能低的算法是我们在设计算法时追求的一个重要目标;另一方面,当给定的问题已有多种算法时,选择其中复杂性最低者,是我们在选用算法适应遵循的一个重要准则。
因此,算法的复杂性分析对算法的设计或选用有着重要的指导意义和实用价值。
简言之,在算法学习过程中,我们必须首先学会对算法的分析,以确定或判断算法的优劣。
1.时间复杂性:
例1:
设一程序段如下(为讨论方便,每行前加一行号)
(1)fori:
=1tondo
(2)forj:
=1tondo
(3)x:
=x+1
......
试问在程序运行中各步执行的次数各为多少?
解答:
行号 次数(频度)
(1)n+1
(2) n*(n+1)
(3) n*n
可见,这段程序总的执行次数是:
f(n)=2n2+2n+1。
在这里,n可以表示问题的规模,当n趋向无穷大时,如果 f(n)的值很小,则算法优。
作为初学者,我们可以用f(n)的数量级O来粗略地判断算法的时间复杂性,如上例中的时间复杂性可粗略地表示为T(n)=O(n2)。
2.空间复杂性:
例2:
将一一维数组的数据(n个)逆序存放到原数组中,下面是实现该问题的两种算法:
算法1:
fori:
=1tondo
b[i]:
=a[n-i+1];
fori:
=1tondo
a[i]:
=b[i];
算法2:
fori:
=1tondiv2do
begin
t:
=a[i];a[i]:
=a[n-i-1];a[n-i-1]:
=t
end;
算法1的时间复杂度为2n,空间复杂度为2n
算法2的时间复杂度为3*n/2,空间复杂度为n+1
显然算法2比算法1优,这两种算法的空间复杂度可粗略地表示为S(n)=O(n)
信息学比赛中,经常是:
只要不超过内存,尽可能用空间换时间。
第二章递归
递归是计算机科学的一个重要概念,递归的方法是程序设计中有效的方法,采用递归编写
程序能是程序变得简洁和清晰.
2.1递归的概念
1.概念
一个过程(或函数)直接或间接调用自己本身,这种过程(或函数)叫递归过程(或函数).
这种方式是直接调用.
这种方式是间接调用.
例1计算n!
可用递归公式如下:
1 当n=0时
fac(n)={n*fac(n-1)当n>0时
例2楼梯有n阶台阶,上楼可以一步上1阶,也可以一步上2阶,编一程序计算共有多少种不同的走法.
设n阶台阶的走法数为f(n)
显然有
1 n=1
f(n)={2 n=2
f(n-1)+f(n-2) n>2
2.2如何设计递归算法
1.确定递归公式
2.确定边界(终了)条件
练习:
用递归的方法完成下列问题
1.求数组中的最大数
2.1+2+3+...+n
3.求n个整数的积
4.求n个整数的平均值
5.求n个自然数的最大公约数与最小公倍数
6.有一对雌雄兔,每两个月就繁殖雌雄各一对兔子.问n个月后共有多少对兔子?
7.已知:
数列1,1,2,4,7,13,24,44,...求数列的第n项.
2.3典型例题
例3梵塔问题
如图:
已知有三根针分别用1,2,3表示,在一号针中从小放n个盘子,现要求把所有的盘子
从1针全部移到3针,移动规则是:
使用2针作为过度针,每次只移动一块盘子,且每根针上
不能出现大盘压小盘.找出移动次数最小的方案.
例4快速排序
快速排序的思想是:
先从数据序列中选一个元素,并将序列中所有比该元素小的元素都放到它的右边或左边,再对左右两边分别用同样的方法处之直到每一个待处理的序列的长度为1,处理结束.
练习:
1.计算ackerman函数值:
n+1 m=0
ack(m,n)={ack(m-1,1) m<>0,n=0
ack(m-1,ack(m,n-1)) m<>0,n<>0
求ack(5,4)
第三章回溯
回溯是按照某种条件往前试探搜索,若前进中遭到失败,则回过头来另择通路继续搜索.
3.1回溯的设计
1.用栈保存好前进中的某些状态.
2.制定好约束条件
例1由键盘上输入任意n个符号;输出它的全排列.
例2.n个皇后问题:
回溯算法的公式如下:
3.2回溯算法的递归实现
由于回溯算法用一栈数组实现的,用到栈一般可用递归实现。
上述例1的递归方法实现如下:
例2:
n皇后问题的递归算法如下:
程序2:
说明:
当n=8时有30条对角线分别用了l和r数组控制,
用c数组控制列.当(i,j)点放好皇后后相应的对角线和列都为false.递归程序如下:
练习:
1.找出所有从m个元素中选取n(n<=m)元素的组合。
2.设有A,B,C,D,E5人从事j1,j2,j3,j4,j55项工作每人只能从事一项,它们的
效益表如下:
j1
j2
j3
j4
j5
A
13
11
10
4
7
B
13
10
10
8
5
C
5
9
7
7
4
D
15
12
10
11
5
E
10
11
8
8
4
求最佳安排,使效益最高.
3.N个数中找出M个数(从键盘上输入正整数N,M后再输入N个正数),要求从N个数中
找出若干个数,使它们的和为M,把满足条件的数组找出来,并统计组数.
4.地图着色。
如下图12个区域用4种颜色着色要求相邻的区域着不同的颜色
5.将任意一正整数(1 如: 4=1+1+1+1 =2+1+1 =2+2 =3+1. 第四章排序 排序就是将杂乱无章的数据元素,通过一定的方法按关键字顺序排列的过程。 4.1简单排序 1.选择排序 选择排序的基本思想是: 对待排序的记录序列进行n-1遍的处理,第1遍处理是将L[1..n]中最小者与L[1]交换位置,第2遍处理是将L[2..n]中最小者与L[2]交换位置,......,第i遍处理是将L[i..n]中最小者与L[i]交换位置。 这样,经过i遍处理之后,前i个记录的位置就已经按从小到大的顺序排列好了。 例1: 输入序列数据按非减顺序输出. 2.插入排序 插入排序的基本思想: 经过i-1遍处理后,L[1..i-1]己排好序。 第i遍处理仅将L[i]插入L[1..i-1]的适当位置p,原来p后的元素一一向右移动一个位置,使得L[1..i]又是排好序的序列。 例2: 输入序列数据按非减顺序输出. 3.冒泡排序 冒泡排序又称交换排序其基本思想是: 对待排序的记录的关键字进行两两比较,如发现两个 记录是反序的,则进行交换,直到无反序的记录为止。 例: 输入序列数据按非减顺序输出。 4.2快速排序 快速排序的思想是: 先从数据序列中选一个元素,并将序列中所有比该元素小的元素都放到它的右边或左边,再对左右两边分别用同样的方法处之直到每一个待处理的序列的长度为1,处理结束. 例: 输入一组数据小到大排序. 4.3希尔排序 基本思想: 将整个无序序列分割成若干小的子序列分别进行插入排序或冒泡排序。 序列分割方法: 将相隔某个增量h的元素构成一个子序列。 在排序过程中,逐次减小这个增量,最后当h减到1时,进行一次插入排序或冒泡排序,排序就完成。 增量序列一般采用: d1=ndiv2,di=di-1div2;i=2,3,4.....其中n为待排序序列的长度。 程序1: (子序列是插入排序) 程序2: (子序列是冒泡排序) 4.4堆排序与二叉树排序 1.堆排序 堆: 设有数据元素的集合(R1,R2,R3,...Rn)它们是一棵顺序二叉树的结点且有 Ri<=R2i和Ri<=R2i+1(或>=) 堆的性质: 堆的根结点上的元素是堆中的最小元素,且堆的每一条路径上的元素都是有序的。 堆排序的思想是: 1)建初始堆(将结点[n/2],[n/2]-1,...3,2,1分别调成堆) 2)当未排序完时 输出堆顶元素,删除堆顶元素,将剩余的元素重新建堆。 2.二叉树排序 排序二叉树: 每一个参加排列的数据对应二叉树的一个结点,且任一结点如果有左(右)子树,则左(右)子树各结点的数据必须小(大)于该结点的数据。 中序遍历排序二叉树即得排序结果。 4.5归并排序 归并就是将多个有序的数列合成一个有序的数列。 将两个有序序列合并为一个有序序列叫二路归并(merge).归并排序就是n长度为1的子序列,两两归并最后变为有序的序列。 1.二路归并 例1: 将有序表L1=(1,5,7),L2=(2,3,4,6,8,9,10)合并一个有序表L. 2.归并排序 4.6线形排序 以上我们讨论的算法均是基于比较的排序算法,在排序算法中有基于数字本身的算法: 计数、桶、基数排序。 1.计数排序 基本思想是对于序列中的每一元素x,确定序列中小于x的元素的个数。 例: n个整数序列且每个值在[1,m],排序之。 2.桶排序 桶排序的思想是若待排序的记录的关键字在一个明显有限范围内(整型)时,可设计有限个有序桶,每个桶装入一个值,顺序输出各桶的值,将得到有序的序列。 例: 输入n个0到100之间的整数,由小到大排序输出。 3.基数排序 基本思想是对n个元素依次按k,k-1,...1位上的数字进行桶排序。 4.7各种排序算法的比较 1.稳定性比较 插入排序、冒泡排序、二叉树排序、二路归并排序及其他线形排序是稳定的 选择排序、希尔排序、快速排序、堆排序是不稳定的 2.时间复杂性比较 插入排序、冒泡排序、选择排序的时间复杂性为O(n2) 其它非线形排序的时间复杂性为O(nlog2n) 线形排序的时间复杂性为O(n); 3.辅助空间的比较 线形排序、二路归并排序的辅助空间为O(n),其它排序的辅助空间为O (1); 4.其它比较 插入、冒泡排序的速度较慢,但参加排序的序列局部或整体有序时,这种排序能达到较快的速度。 反而在这种情况下,快速排序反而慢了。 当n较小时,对稳定性不作要求时宜用选择排序,对稳定性有要求时宜用插入或冒泡排序。 若待排序的记录的关键字在一个明显有限范围内时,且空间允许是用桶排序。 当n较大时,关键字元素比较随机,对稳定性没要求宜用快速排序。 当n较大时,关键字元素可能出现本身是有序的,对稳定性有要求时,空间允许的情况下。 宜用归并排序。 当n较大时,关键字元素可能出现本身是有序的,对稳定性没有要求时宜用堆排序。 第五章查找(检索) 查找是在数据结构中查找指定值的结点。 5.1顺序查找 1.顺序查找的思想是是: 将查找值顺序逐个与结点值进行比较,相等即为查找成功,否则查找失败. 5.2二分查找 1.二分查找的基本思想: 首先将结点按关键字排序,其次将查找值与中间位置的值比较,相等,查找成功;不等,则中间数据大于或小于查找值,无论怎样查找将在一半的数据中查找。 2.例: 输入序列数据查找指定值. 5.3二叉排序树查找 因为二叉排序树的左子树若不为空则左子树的所有结点的值均小于它的根结点的值,而右子树若不为空,则右子树的所有结点的值均不小大于它的根结点的值,根据这个性质查找算法如下: 5.4哈希(Hash)表 以上讲的查找方法基于比较的,查找效率依赖比较次数,其实理想的查找希望不经比较,一次存取便能得到所查记录,那就必须在记录的存储位置和它的关键字之间建立一个确定的对应关系f,这样查找k时,只要根据这个对应关系f找到给定值k的像f(k)。 这种对应关系f叫哈希(hash)函数。 按这种思想建立的表叫哈希表(也叫散列表)。 哈希表存取方便但存储时容易冲突(collision): 即不同的关键字可以对应同一哈希地址。 如何确定哈希函数和解决冲突是关键。 1.哈希函数的构造方法 直接定址法: H(k)=k或H(k)=a*k+b(线形函数) 如: 人口数字统计表 地址 1 2 3 ... 100 年龄 1 2 3 ... 100 人数 67 3533 244 ... 4 数字分析法: 取关键字的若干数位组成哈希地址 如: 关键字如下: 若哈希表长为100则可取中间两位10进制数作为哈希地址。 81346532 81372242 81387422 81301367 81322817 81338967 81354157 81368537 平方取中法: 关键字平方后取中间几位数组成哈希地址 折叠法: 将关键数字分割成位数相同的几部分(最后一部分的位数可以不同)然后取几部分的叠加和(舍去进位)作为哈希地址。 除留余数法: 取关键字被某个不大于表长m的数p除后所得的余数为哈希地址。 H(k)=kmodp p<=m 随机数法: H(k)=rondom(k)。 2.处理冲突的方法 假设地址集为0..n-1,由关键字得到的哈希地址为j(0<=j<=n-1)的位置已存有记录,处理冲突就是为该关键字的记录找到另一个"空"的哈希地址。 在处理中可能得到一个地址序列Hii=1,2,...k 0<=Hi<=n-1),即在处理冲突时若得到的另一个哈希地址H1仍发生冲突,再求下一地址H2,若仍冲突,再求H3...。 怎样得到Hi呢? 开放定址法: Hi=(H(k)+di)modm (H(k)为哈希函数;m为哈希表长;di为增量序列) 当di=1,2,3,...m-1时叫线性探测再散列。 当di=12,-12,22,-22,32,-32,...,k2,-k2时叫二次探测再散列。 当di=random(m)时叫伪随机探测序列。 例: 长度为11的哈希表关键字分别为17,60,29,哈希函数为H(k)=kmod11,第四个记录的关键字为38,分别按上述方法添入哈希表的地址为8,4,3(随机数=9)。 再哈希法: Hi=RHi(key)i=1,2,...,k,其中RHi均为不同的哈希函数。 链地址法: 这种方法很象基数排序,相同的地址的关键字值均链入对应的链表中。 建立公益区法: 另设一个溢出表,不管得到的哈希地址如何,一旦发生冲突,都填入溢出表。 3.哈希表的查找 例: 如下一组关键字按哈希函数H(k)=kmod13和线性探测处理冲突所得的哈希表a[0..15]: 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 14 01 68 27 55 19 20 84 79 23 11 10 当给定值k=84,则首先和a[6]比在依次和a[7],a[8]比结果a[8]=84查找成功。 当给定值k=38,则首先和a[12]比,再和a[13]比,由于a[13]没有,查找不成功,表中不存在关键字等于38的记录。 5.5查找第k小元素 查找第k小元素即在n个元素中(未排序)找到第k小的元素。 方法同快速排序,采用递归方式。 第六章穷举(枚举)策略 6.1穷举策略的概念 所谓枚举法,指的是从可能的解的集合中一一枚举各元素,用题目给定的检验条件判定哪些是无用的,哪些是有用的。 能使命题成立,即为其解。 有些问题可以用循环语句和条件语句直接求解,有些问题用循环求解时循环次数太多,无法编写程序,怎么办? 下面是用“千军万马过独木桥,适者存”的方式实现穷举策略的。 6.2典型例题与习题 例1.将2n个0和2n个1,排成一圈。 从任一个位置开始,每次按逆时针的方向以长度为n+1的单位进行数二进制数。 要求给出一种排法,用上面的方法产生出来的2n+1个二进制数都不相同。 例如,当n=2时,即22个0和22个1排成如下一圈: 比如,从A位置开始,逆时针方向取三个数000,然后再从B位置上开始取三个数001,接着从C开始取三个数010,...可以得到000,001,010,101,011,111,110,100共8个二进制数且都不相同。 例2: 在A、B两个城市之间设有N个路站(如下图中的S1,且N<100),城市与路站之间、路站和路站之间各有若干条路段(各路段数<=20,且每条路段上的距离均为一个整数)。 A,B的一条通路是指: 从A出发,可经过任一路段到达S1,再从S1出发经过任一路段,…最后到达B。 通路上路段距离之和称为通路距离(最大距离<=1000)。 当所有的路段距离给出之后,求出所有不同距离的通路个数(相同距离仅记一次)。 例如: 下图所示是当N=1时的情况: 从A到B的通路条数为6,但因其中通路5+5=4+6,所以满足条件的不同距离的通路条数为5。 算法说明: 本题采用穷举算法。 数据结构: N: 记录A,B间路站的个数 数组D[I,0]记录第I-1个到第I路站间路段的个数 D[I,1],D[I,2],…记录每个路段距离 数组G记录可取到的距离 练习: 1、问题描述: 将n个整数分成k组(k≤n,要求每组不能为空),显然这k个部分均可得到一个各自的和s1,s2,……sk,定义整数P为: P=(S1-S2)2+(S1一S3)2+……+(S1-Sk)2+(s2-s3)2+……+(Sk-1-Sk)2 问题求解: 求出一种分法,使P为最小(若有多种方案仅记一种〉 程序说明: 数组: a[1],a[2],...A[N]存放原数 s[1],s[2],...,s[K]存放每个部分的和 b[1],b[2],...,b[N]穷举用临时空间 d[1],d[2],...,d[N]存放最佳方案 2.问题描述: 有n种基本物质(n≤10),分别记为P1,P2,……,Pn,用n种基本物质构造物品,这些物品使用在k个不同地区(k≤20),每个地区对物品提出自己的要求,这些要求用一个n 位的数表示: α1α2……αn,其中: αi=1表示所需物质中必须有第i种基本物质 =-1表示所需物质中必须不能有第i种基本物质r =0无所谓 问题求解: 当k个不同地区要求给出之后,给出一种方案,指出哪些物质被使用,哪些物质不被使用。 程序说明: 数组b[1],b[2],...,b[nJ表示某种物品 a[1..k,1..n]记录k个地区对物品的要求,其中: a[I,j]=1表示第i个地区对第j种物品是需要的 a[i,j]=0表示第i个地区对第j种物品是无所谓的 a[i,j]=-1表示第i个地区对第j种物品是不需要的 第七章贪心策略 在众多的计算机解题策略中,贪心策略可以算得上是最接近人们日常思维的一种解题策略,正基于此,贪心策略在各级各类信息学竞赛、尤其在对NPC类问题的求解中发挥着越来越重要的作用。 7.1贪心策略的定义 贪心策略是: 指从问题的初始状态出发,通过若干次的贪心选择而得出最优值(或较优解)的一种解题方法。 其实,从“贪心策略”一词我们便可以看出,贪心策略总是做出在当前看来是最优的选择,也就是说贪心策略并不是从整体上加以考虑,它所做出的选择只是在某种意义上的局部最优解,而许多问题自身的特性决定了该题运用贪心策略可以得到最优解或较优解。 例1: 在n行m列的正整数矩阵中,要求从每一行中选一个数,使得选出的n个数的和最大。 本题可用贪心策略: 选n次,每一次选相应行中的最大值即可。 例2: 在一个N×M的方格阵中,每一格子赋予一个数(即为权)。 规定每次移动时只能向上或向右。 现试找出一条路径,使其从左下角至右上角所经过的权之和最大。 本题用贪心策略不能得到最优解,我们以2×4的矩阵为例。 3 4 6 1 2 10 若按贪心策略求解,所得路径为: 1,3,4,6; 若按动态规划法求解,所得路径为: 1,2,10,6。 例3: 设定有n台处理机p1,p2,......pn,和m个作业j1,j2,...jm,处理机可并行工作,作业未完成不能中断,作业ji在处理机上的处理时间为ti,求解最佳方案,使得完成m项工作的时间最短? 本题不能用贪心算法求解: 理由是若n=3,m=6各作业的时间分别是11 7 5 5 4 7 用贪心策略解(每次将作业加到最先空闲的机器上)time=15,用搜索策略最优时间应是14,但是贪心策略给我们提供了一个线索那就是每台处理上的时间不超过15,给搜索提供了方便。 总之: 1.不能保证求得的最后解是最佳的; 2.只能用来求某些最大或最小解问题; 3.能确定某些问题的可行解的范围,特别是给搜索算法提供了依据。 7.2贪心策略的特点 贪心算法有什么样的特点呢? 我认为,适用于贪心算法解决的问题应具有以下2个特点: 1、贪心选择性质: 所谓贪心选择性质是指应用同一规则f,将原问题变为一个相似的、但规模更小的子问题、而后的每一步都是当前看似最佳的选择。 这种选择依赖于已做出的选择,但不依赖于未做出的选择。 从全局来看,运用贪心策略解决的问题在程序的运行过程中无回溯过程。 关于贪心选择性质,读者可在后文给出的贪心策略状态空间图中得到深刻地体会。 2、局部最优解: 我们通过特点2向大家介绍了贪心策略的数学描述。 由于运用贪心策略解题在每一次都取得了最优解,但能够保证局部最优解得不一定是贪心算法。 如大家所熟悉得动态规划算法就可以满足局部最优
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 信息 基础知识 常用 算法 策略