NOIP基础算法--枚举、递推和递归ppt课件.ppt





《NOIP基础算法--枚举、递推和递归ppt课件.ppt》由会员分享,可在线阅读,更多相关《NOIP基础算法--枚举、递推和递归ppt课件.ppt(115页珍藏版)》请在淘文阁 - 分享文档赚钱的网站上搜索。
1、NOIP基础算法综合n枚举法的基本思想是根据提出的问题枚举所有可能状态,并用问题给定的条件检验哪些是需要的,哪些是不需要的。能使命题成立,即为其解。n枚举结构:循环+判断语句。 n 虽然枚举法本质上属于搜索策略,但是它与后面讲的回溯法有所不同。因为适用枚举法求解的问题必须满足两个条件:n 可预先确定每个状态的元素个数n;n 状态元素a1,a2,an的可能值为一个连续的值域。n设ai1状态元素ai的最小值;aik状态元素ai的最大值(1in),即a11a1a1k,a21a2a2k, ai1aiaik,an1anankfor a1a11 to a1k do for a2a21 to a2k do
2、for aiai1 to aik do for anan1 to ank do if 状态(a1,ai,an)满足检验条件 then 输出问题的解;枚举法的优点枚举法的优点n由于枚举算法一般是现实生活中问题的“直译”,因此比较直观,易于理解;n由于枚举算法建立在考察大量状态、甚至是穷举所有状态的基础上,所以算法的正确性比较容易证明。枚举法的缺点枚举法的缺点n枚举算法的效率取决于枚举状态的数量以及单个状态枚举的代价,因此效率比较低。四、枚举法的优缺点四、枚举法的优缺点n“直译”枚举:直接根据题意设定枚举对象、范围和约束条件。n 注意认真审题,不要疏漏任何条件例题例题1 1:砝码称重:砝码称重(n
3、oip1996) (noip1996) 【问题描述问题描述】设有1g、2g、3g、5g、10g、20g的砝码各若干枚(其总重=1000),求用这些砝码能称出不同的重量个数。【文件输入文件输入】输入1g、2g、3g、5g、10g、20g的砝码个数。【文件输出文件输出】输出能称出不同重量的个数。【样例输入样例输入】1 1 0 0 0 0【样例输出样例输出】3 3 【分析分析】根据输入的砝码信息,每种砝码可用的最大个数是确定的,而且每种砝码的个数是连续的,能取0到最大个数,所以符合枚举法的两个条件,可以使用枚举法。枚举时,重量可以由1g,2g,20g砝码中的任何一个或者多个构成,枚举对象可以确定为6
4、种重量的砝码,范围为每种砝码的个数。判定时,只需判断这次得到的重量是新得到的,还是前一次已经得到的,即判重。由于重量=1000g,所以,可以开一个a1001的数组来判重。readln(a,b,c,d,e,f)for c1:=0 to a do /1g砝码的个数砝码的个数 for c2:=0 to b do /2g砝码的个数砝码的个数 for c3:=0 to c do /3g砝码的个数砝码的个数 for c4:=0 to d do /5g砝码的个数砝码的个数 for c5:=0 to e do /10g砝码的个数砝码的个数 for c6:=0 to f do /20g砝码的个数砝码的个数 be
5、gin sum:=0; for i:=1 to 6 do sum:=sum+ci*wi; asum:=1; /标记标记 end;for i:=1 to 1000 do if ai=1 then inc(num); /统计不同重量的个数统计不同重量的个数Writeln(num);【问题描述】给你n根火柴棍,你可以拼出多少个形如“A+B=C”的等式?等式中的A、B、C是用火柴棍拼出的整数(若该数非零,则最高位不能是0)。用火柴棍拼数字0-9的拼法如图所示:注意: 1. 加号与等号各自需要两根火柴棍 2. 如果AB,则A+B=C与B+A=C视为不同的等式(A、B、C0) 3. n根火柴棍必须全部用上
6、【输入】输入文件matches.in共一行,又一个整数n(n24)。【输出】输出文件matches.out共一行,表示能拼成的不同等式的数目。 例题例题2 2:火柴棒等式(:火柴棒等式(NOIP2008NOIP2008)例题例题2 2:火柴棒等式(:火柴棒等式(NOIP2008NOIP2008) 【问题简述问题简述】给你n(n=A,满足条件的A的最大取值为1111。所以枚举A和B的范围是从01111。n为了加快速度,可以将为了加快速度,可以将0 0到到22222222的所有整数需的所有整数需要的火柴棒数目提前算好保存在数组中。要的火柴棒数目提前算好保存在数组中。五、枚举算法的优化枚举算法的优化
7、 枚举算法的时间复杂度:状态总数*单个状态的耗时。n 提取有效信息;n 减少重复计算;n 将原问题化为更小的问题;n 根据问题的性质进行截枝;n 引进其他算法【例题例题3 3】给你给你n(nn(n=10=105 5) )个整数,然后要有个整数,然后要有m m (m=10(m=105 5) )个询问。每个询问两个整数个询问。每个询问两个整数i i和和j j,问第,问第i i个个数字到第数字到第j j个数字所有数字之和。个数字所有数字之和。【朴素算法朴素算法】 readln(n); for i:=1 to n do read(ai); for i:=1 to m do begin read(x,y
8、); sum:=0; for j:=x to y do sum:=sum+aj; writeln(sum); end;时间复杂度为:时间复杂度为:O(nm)【优化算法优化算法】先递推计算出先递推计算出si=si-1+ai,再回答询问情况,再回答询问情况; readln(n); for i:=1 to n do统计求和统计求和 begin read(ai); si:=si-1+ai; end; for i:=1 to m do begin read(x,y); writeln(sy-sx-1); end;【例题例题4 4】对于给定的对于给定的N N* *MM的矩形,在其中找一个的矩形,在其中找一
9、个R R* *C C的权值最大的区域的权值最大的区域, 1=N,M=1,000, 1=N,M=1,000。【算法一算法一】:以每一个格子为左上角枚举:以每一个格子为左上角枚举R*C的区的区域,并求出它的权值之和。最后取其中的最大值。域,并求出它的权值之和。最后取其中的最大值。此算法包含此算法包含4重循环。重循环。 时间复杂度:时间复杂度:O(N4) 【算法二算法二】:我们设:我们设Si,j表示以表示以(1,1)为左上角,为左上角,(i,j)为右为右下角区域的权值之和,那么我们以下角区域的权值之和,那么我们以(i,j)为右下角的为右下角的R*C区区域权值之和的计算公式为:域权值之和的计算公式为:
10、 Areai,j=Si,j+Si-R,j-C-Si-R,j-Si,j-C其中其中Si,j的计算公式为:的计算公式为: Si,j=valuei,j+Si-1,j+Si,j-1-Si-1,j-1 你可以随手画图出来,很容易即可证明上面两个式你可以随手画图出来,很容易即可证明上面两个式子。最后取子。最后取Area中的最大值即可。中的最大值即可。 时间复杂度:时间复杂度:O(N2) 【例题例题5 5】最大连续子序列的和最大连续子序列的和 【问题描述】给你一个有n(nmaxx then maxx:=sum; end;【算法算法22:优化的枚举:优化的枚举O(O(nn2)2) s0:=0; for i:=
11、1 to n do si:=si-1+ai;/初始化求和初始化求和 maxxmaxx:=a1;:=a1; for i:=1 to n do for i:=1 to n do for j:=i to n do for j:=i to n do if sj-si-1 if sj-si-1maxxmaxx then then maxxmaxx:=sj-si-1;:=sj-si-1;时间复杂度:预处理+主程序=O(n+n2)=O(n2),n=5000 【算法3】分治分治O O( (n nloglogn n) )、 最大连续子序列的位置有三种可能: 完全处于序列的左半; 完全处于序列的右半; 跨越序列中
12、间; 【算法算法4 4】DPDPO O( (n n) ) 1 1、阶段和状态、阶段和状态: 以第i个数结尾的最大连续子序列的和,只存在两种选择: 情形1:只包含ai 情形2:包含ai和以ai-1结尾的最大连续和序列 故设fi表示以ai结尾的最大连续子序列的和 2 2、状态转移方程:、状态转移方程: 转移方程:fi=maxai,fi-1+ai(2=i=n) 初始化:f1=a1 Answer=maxfi|1=ibest then best:=sum;/调整最优解调整最优解 end;n这个算法相当粗糙,枚举状态的费用为这个算法相当粗糙,枚举状态的费用为O(n6)(x1,y1)(x2,y2)2 2、从
13、减少重复计算入手、从减少重复计算入手 n有刚才一维情况可以推广到二维,在统计左上角为有刚才一维情况可以推广到二维,在统计左上角为(x1,y1)右下角右下角为为(x2,y2)内矩形的元素之和时,我们同样可以先初始化,计算出左内矩形的元素之和时,我们同样可以先初始化,计算出左上角为上角为(1,1),右下角为,右下角为(x,y)内矩形的元素之和内矩形的元素之和sxy。 for i:=1 to n do /枚举矩形右下角,求和枚举矩形右下角,求和 for j:=1 to n do begin read(ai,j); si,j:=si-1,j+si,j-1-si-1,j-1+ai,j; end;n对于状
14、态左上角为对于状态左上角为(x1,y1),右下角为右下角为(x2,y2)内矩形的元素之和,可内矩形的元素之和,可以改为:以改为: sum:=sx2,y2-sx1-1,y2-sx2,y1-1+sx1-1,y1-1; if sumbest then best:=sum; /调整最优解调整最优解n由于先进行了由于先进行了,整个算法的时间复杂度降为,整个算法的时间复杂度降为O(n4)3、提取恰当的信息、提取恰当的信息n容易观察到,最大子矩阵问题是最大连续子序列和问题的提升,即将一条线换成一个面,将一维问题提升到二维问题。所以我们计算最大子矩阵的方法就是将一行行的数进行累加以求得最大值。n但是还有一个问
15、题,那就是应该如何高效地存储矩阵?n我们可以想到:在一个一维的数列中,设数组bi表示从第1个元素到第i个元素的和,则如果想要求第i个元素到第j个元素的和,只需要计算bj-bi-1的值就行了。由此推广到二维矩阵,设bi,j表示矩阵第j列前i个元素的和,ai,j表示元素数据,则压缩存储: for i:=1 to n do for j:=1 to n do begin read(ai,j);bi,j:=bi-1,j+ai,j;n因此,我们可以使用三重循环求出所有的矩形值,即枚举起始行枚举起始行i和终和终止行止行j,压缩子矩形成为一行,变成一维求最大子段和问题,压缩子矩形成为一行,变成一维求最大子段和
16、问题。 即tk=max(tk-1,0)+bj,k-bi-1,k;n时间复杂度为O(n3)0 -2 -7 09 2 -6 2-4 1 -4 1-1 8 0 -20 -2 -7 09 0 -13 25 1 -17 34 9 -17 1核心代码核心代码 sum:=-99999999; /置初值置初值 for i:=1 to n do /阶段阶段:起始行起始行 begin for j:=i to n do /状态状态:结束行结束行 begin t1:=bj,1-bi-1,1; /初始化第初始化第1列的值列的值 for k:=2 to n do /决策决策:第几列第几列 begin if tk-10 t
17、hen tk:=tk-1+bj,k-bi-1,k else tk:=bj,k-bi-1,k; if tksum then sum:=tk; end; end; end; writeln(sum);例题例题7 7:求第一、第二、第三最短路问题:求第一、第二、第三最短路问题n 重庆城里有重庆城里有n n个车站,个车站,mm条双向公路连接其中的某些车站。条双向公路连接其中的某些车站。每两个车站最多用一条公路直接相连,从任何一个车站出每两个车站最多用一条公路直接相连,从任何一个车站出发都可以经过一条或多条公路到达其他车站,但不同的路发都可以经过一条或多条公路到达其他车站,但不同的路径需要花费的时间可能
18、不同。在一条路上花费的时间等于径需要花费的时间可能不同。在一条路上花费的时间等于路径上所有公路需要的时间之和。路径上所有公路需要的时间之和。n 佳佳的家在车站佳佳的家在车站1 1,他有五个亲戚,分别住在车站,他有五个亲戚,分别住在车站a,b,c,d,ea,b,c,d,e。过年了,他需要从自己的家出发,拜访每个亲。过年了,他需要从自己的家出发,拜访每个亲戚(顺序任意),给他们送去节日的祝福。怎样走,才需戚(顺序任意),给他们送去节日的祝福。怎样走,才需要最少的时间?要最少的时间?n 数据范围:数据范围:n(nn(n=50,000),m(m=100,000)=50,000),m(mnnn0 0时时
19、, ,可以用等号可以用等号( (或大于号、小于号或大于号、小于号) )将将HnHn与其前面的某些项与其前面的某些项Hn(0in)Hn(0in)联系起来,这样的联系起来,这样的式子就叫做递推关系。式子就叫做递推关系。如何建立递推关系如何建立递推关系递推关系有何性质递推关系有何性质如何求解递推关系如何求解递推关系 n 建立递推关系式建立递推关系式n 确定边界条件确定边界条件n 递推求解递推求解 n 一般递推问题一般递推问题n 组合计数类问题组合计数类问题n 一类博弈问题的求解一类博弈问题的求解n 动态规划问题的递推关系动态规划问题的递推关系例题例题1 1:faibonaccifaibonacci数
20、列数列 【问题描述问题描述】已知faibonacci数列的前几个数分别为0,1,1,2,3,5,编程求出此数列的第n项。(n=60) 例题例题2 2:输出杨辉三角的前:输出杨辉三角的前N N行行 【问题描述问题描述】输出杨辉三角的前N行(N10)。【文件输入文件输入】输入只有一行,包括1个整数N(N2)个盘子时,我们可以利用下列步骤:n 第一步:先借助3柱把1柱上面的n-1个盘子移动到2柱上,所需的 移动次数为f(n-1)。n 第二步:然后再把1柱最下面的一个盘子移动到3柱上,只需要1 次盘子。n 第三步:再借助1柱把2柱上的n-1个盘子移动到3上,所需的移动 次数为f(n-1)。n 由以上3
21、步得出总共移动盘子的次数为:f(n-1)+1+ f(n-1)。n 所以:f(n)=2 f(n-1)+1 hn=2hn-1+1 =2n-1 边界条件:h1=1【扩展扩展2】:四塔问题:四塔问题【问题分析问题分析】令令fi表示四个柱子时,把表示四个柱子时,把i个盘子从原柱移动到目标柱所需的个盘子从原柱移动到目标柱所需的最少移动次数。最少移动次数。 jn第一步:先把1柱上的前j个盘子移动到另外其中一个非目标柱(2或3柱均可,假设移到2柱)上,此时3和4柱可以作为中间柱。移动次数为:fj。n第二步:再把原1柱上剩下的i-j个盘子在3根柱子(1、3、4)之间移动,最后移动到目标柱4上,因为此时2柱不能作
22、为中间柱子使用,根据三柱问题可知,移动次数为:2(i-j)-1。n第三步:最后把非目标柱2柱上的j个盘子移动到目标柱上,次数为:fj。 in通过以上步骤我们可以初步得出:通过以上步骤我们可以初步得出: fi = 2*fj+2(i-j)-1nj可取的范围是可取的范围是1=ji,所以对于不同的,所以对于不同的j,得到的,得到的fi可能可能是不同的,本题要求最少的移动次数。是不同的,本题要求最少的移动次数。 fi=min2*fj+2(i-j)-1,其中1=ji【扩展扩展3】:m塔问题塔问题【问题分析问题分析】 设F(m,n)为m根柱子,n个盘子时移动的最少次数:n 1、先把1柱上的前j个盘子移动到另
23、外其中一个除m柱以外的非目标柱上,移动次数为:fm, j; n 2、再把原1柱上剩下的n-j个盘子在m-1根柱子之间移动,最后移动到目标柱m上,移动次数为:fm-1, n-j;n 3、最后把非目标柱上的j个盘子移动到目标柱没柱上,移动次数为:fm, j。F(m,n)=min2*F(m,j)+F(m-1,n-j) (1=jn)j 例题例题4:4:数的计数数的计数 【问题描述】我们要求找出具有下列性质数的个数(包含输入的自然数n),先输入一个自然数n(n1000),然后对此自然数按照如下方法进行处理: (1)、不作任何处理; (2)、在它的左边加上一个自然数,但该自然数不能超过原数的一半; (3)
24、、加上数后,继续按此规则进行处理,直到不能再加自然数为止; 方法方法1 1:用递推用递推n 用hn表示自然数n所能扩展的数据个数,则: h1=1,h2=2,h3=2,h4=4,h5=4, h6=6,h7=6,h8=10,h9=10。n 分析上数据,可得递推公式: hi=1+h1+h2+hi/2。n 时间复杂度O(n2)。 方法方法2 2:是对方法:是对方法1 1的改进的改进。我们定义数组s。 s(x)=h(1)+h(2)+h(x) =s(x-1)+h(x) =s(x-1)+s(x/2) h(x)=s(x)-s(x-1)=s(x/2) 此算法的时间复杂度可降到O(n)。方法方法3 3:还是用递推
25、:还是用递推。n只要做仔细分析,其实我们还可以得到以下的递推公式: (1)当i为奇数时,h(i)=h(i-1); (2) 当i为偶数时,h(i)=h(i-1)+h(i/2);【思考思考】 1.1.若若n=10000n=10000怎么计算;怎么计算; 2.2.若若n=3000000n=3000000怎么计算;怎么计算;n例题例题5 5:猴子吃桃问题:猴子吃桃问题15381538n 【问题描述问题描述】猴子摘了一堆桃,第一天吃了一半,猴子摘了一堆桃,第一天吃了一半,还嫌不过瘾,又吃了一个;第二天又吃了剩下的还嫌不过瘾,又吃了一个;第二天又吃了剩下的一半零一个;以后每天如此。到第一半零一个;以后每天
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- NOIP 基础 算法 枚举 递归 ppt 课件

限制150内