枚举搜索与动态规划试题精讲课件.ppt
《枚举搜索与动态规划试题精讲课件.ppt》由会员分享,可在线阅读,更多相关《枚举搜索与动态规划试题精讲课件.ppt(83页珍藏版)》请在淘文阁 - 分享文档赚钱的网站上搜索。
1、枚举、搜索与动态规划试 题 精 讲朱全民枚举 所谓枚举法所谓枚举法,指的是从可能的解集合中一一枚举各指的是从可能的解集合中一一枚举各元素元素,用题目给定的检验条件判定哪些是无用的用题目给定的检验条件判定哪些是无用的,哪些是有用的哪些是有用的.能使命题成立能使命题成立,即为其解。一般思即为其解。一般思路:路:对命题建立正确的数学模型;对命题建立正确的数学模型;根据命题确定的数学模型中各变量的变化范围根据命题确定的数学模型中各变量的变化范围(即可能解的范围);(即可能解的范围);利用循环语句、条件判断语句逐步求解或证明;利用循环语句、条件判断语句逐步求解或证明;枚举法的特点是算法简单,但有时运算量
2、大。对枚举法的特点是算法简单,但有时运算量大。对于可能确定解的值域又一时找不到其他更好的算于可能确定解的值域又一时找不到其他更好的算法时可以采用枚举法。法时可以采用枚举法。枚举法求解的问题必须满足两个条件:枚举法求解的问题必须满足两个条件:可预先确定每个状态的元素个数可预先确定每个状态的元素个数n;状态元素状态元素a1,a2,an的可能值为一个连续的值域。的可能值为一个连续的值域。设设ai1状状态态元元素素ai的的最最小小值值;aik状状态态元元素素ai的的最最大大值值(1in)即即a11a1a1k,a21a2a2k,ai1aiaik,an1anankfora1a11toa1kdofoa2a2
3、1toa2kdoforanan1toankdoif状态状态(a1,ai,an)满足检验条件满足检验条件then输出问题的解;输出问题的解;枚举算法的优化枚举算法的优化枚枚举举算算法法的的时时间间复复杂杂度度可可以以用用状状态态总总数数*考考察察单单个个状状态态的的耗耗时时来表示,因此优化主要是来表示,因此优化主要是减少状态总数(即减少枚举变量和枚举变量的值域)减少状态总数(即减少枚举变量和枚举变量的值域)降低单个状态的考察代价降低单个状态的考察代价优化过程从几个方面考虑。具体讲优化过程从几个方面考虑。具体讲提取有效信息提取有效信息减少重复计算减少重复计算将原问题化为更小的问题将原问题化为更小的
4、问题根据问题的性质进行截枝根据问题的性质进行截枝引进其他算法引进其他算法侦探推理侦探推理(NOIP20032)证词中出现的其他话,都不列入逻辑推理的内容。证词中出现的其他话,都不列入逻辑推理的内容。明明明明所所知知道道的的是是,他他的的同同学学中中有有N N个个人人始始终终说说假假话话,其其余余的的人始终说真话。人始终说真话。现现在在,明明明明需需要要你你帮帮助助他他从从他他同同学学的的话话中中推推断断出出谁谁是是真真正正的凶手,请记住,的凶手,请记住,凶手只有一个!凶手只有一个!要求:要求:判断谁是罪犯?判断谁是罪犯?分析这道题的关键点是这道题的关键点是“如何能够快速正确实现出来如何能够快速
5、正确实现出来”,事实,事实上这道题对编码能力的要求要大于对算法本身的要求。由上这道题对编码能力的要求要大于对算法本身的要求。由于这道题的数据范围并不是很大,但需要进行于这道题的数据范围并不是很大,但需要进行“字符串处字符串处理理”这种比较麻烦的工作,因此在比赛时就可以采用效率这种比较麻烦的工作,因此在比赛时就可以采用效率低一些的枚举算法来换取编码上的简单。低一些的枚举算法来换取编码上的简单。推荐的算法分为两步:推荐的算法分为两步:1 1预处理每个人的每一句话,并把它们分类处理;预处理每个人的每一句话,并把它们分类处理;2 2枚举罪犯和当前星期几,找出所有可能发生的情况。枚举罪犯和当前星期几,找
6、出所有可能发生的情况。下面我们来逐步细化一下每一步的算法,对于第一步,我下面我们来逐步细化一下每一步的算法,对于第一步,我们希望的是把一些杂乱的不好处理的们希望的是把一些杂乱的不好处理的“字符串信息字符串信息”转化转化为相对比较好处理的信息。为此,我们可以通过把为相对比较好处理的信息。为此,我们可以通过把“信息信息”进行分类的方法使得对于每一类信息,更加方便的处理进行分类的方法使得对于每一类信息,更加方便的处理(即我们可以用一个或者几个变量来表示),由题目描述(即我们可以用一个或者几个变量来表示),由题目描述可以发现语句可分为三类:可以发现语句可分为三类:分析1 1指明指明i i是否是罪犯的语
7、句;是否是罪犯的语句;2 2指明今天是星期指明今天是星期d d的语句;的语句;3 3没有意义的语句没有意义的语句(不符合格式要求不符合格式要求)。我们必须要说明的是任何不符合格式要求的语句都将被划我们必须要说明的是任何不符合格式要求的语句都将被划分到第三类中去,这样在处理每个语句的时候就必须要考分到第三类中去,这样在处理每个语句的时候就必须要考虑该语句是否符合格式要求,通过以上的处理,我们对于虑该语句是否符合格式要求,通过以上的处理,我们对于每一个语句用几个变量就可以表示了。每一个语句用几个变量就可以表示了。对于第二步的细化,我们在枚举完罪犯和当前星期几之后,对于第二步的细化,我们在枚举完罪犯
8、和当前星期几之后,就可以比较方便的判断每一句话的真伪了,这样我们再根就可以比较方便的判断每一句话的真伪了,这样我们再根据每个人所说的话把人进行分类。据每个人所说的话把人进行分类。1 1没说任何一句有意义的话;没说任何一句有意义的话;2 2只说真话;只说真话;3 3只说假话;只说假话;4 4既说真话也说假话。既说真话也说假话。分析需要注意的是,对于第一类人我们既可以把他当成说真话需要注意的是,对于第一类人我们既可以把他当成说真话的,也可以把他当成说假话的,而如果第四类人存在的话,的,也可以把他当成说假话的,而如果第四类人存在的话,那么从他本身就可以推出矛盾了。那么从他本身就可以推出矛盾了。最后,
9、如果对于罪犯最后,如果对于罪犯i i存在一个存在一个d d使得当前情况是可能的,使得当前情况是可能的,我们就说我们就说i i就是可能的罪犯。就是可能的罪犯。时间效率时间效率 O(MP|Day|)O(MP|Day|)(其中(其中Day=SundayDay=Sunday,Monday,Tuesday,Monday,Tuesday,Wednesday,Thursday,Friday,SaturdayWednesday,Thursday,Friday,Saturday)优化我们可以发现在对罪犯和当前星期几进行我们可以发现在对罪犯和当前星期几进行“双重枚举双重枚举”时,时,进行了很多重复的操作,于是我们
10、想到,能不能不枚举是当进行了很多重复的操作,于是我们想到,能不能不枚举是当前星期几?这样我们把这类语句与判断罪犯的语句分离,可前星期几?这样我们把这类语句与判断罪犯的语句分离,可以先由判断罪犯的语句中确定一部分人肯定说真话,一部分以先由判断罪犯的语句中确定一部分人肯定说真话,一部分人肯定说假话,剩下的一部分人就要根据他所说的当前星期人肯定说假话,剩下的一部分人就要根据他所说的当前星期几的语句来判断了,首先我们假设所有人判断星期的语句不几的语句来判断了,首先我们假设所有人判断星期的语句不自相矛盾,这样每个人将在判断这类问题里面至多有一个答自相矛盾,这样每个人将在判断这类问题里面至多有一个答案,我
11、们便可以统计判断当前是星期案,我们便可以统计判断当前是星期d d的总人数,于是改进的总人数,于是改进后的算法对于每一个可能的罪犯,先用后的算法对于每一个可能的罪犯,先用O(p)O(p)的时间处理所有的时间处理所有的话,再用的话,再用O(|Day|)O(|Day|)的时间枚举星期几。这样,改进后算法的时间枚举星期几。这样,改进后算法的复杂度就是的复杂度就是O(m(p+|Day|)O(m(p+|Day|)。那么我们可不可以再进一步,把算法优化到线性?这里面可那么我们可不可以再进一步,把算法优化到线性?这里面可以比较明确地告诉大家,是可以做到的,具体的算法类似于以比较明确地告诉大家,是可以做到的,具
12、体的算法类似于上面的按照语句的种类分离语句,只是分离得更细,处理得上面的按照语句的种类分离语句,只是分离得更细,处理得更复杂,在这里就不做赘述,留给大家思考。更复杂,在这里就不做赘述,留给大家思考。现有一个棱长为现有一个棱长为n的立方体,可以分成的立方体,可以分成n3个个1*1*1的单位立方体。每个单位立方体都有的单位立方体。每个单位立方体都有一个整数值。一个整数值。n3个单位立方体的数和不会超过个单位立方体的数和不会超过longint范围。现在要求在这个立方体找范围。现在要求在这个立方体找到一个包含完整单位立方体的长方体,使得该长方体内所有单位立方体的数和最大。到一个包含完整单位立方体的长方
13、体,使得该长方体内所有单位立方体的数和最大。输输入入:n(1n20);n个个n*n的的数数字字矩矩阵阵,每每个个数数字字矩矩阵阵代代表表一一层层,每每个个数数字字代代表表一一个个单位立方体的整数值,单位立方体的整数值,-999单位立方体的整数值单位立方体的整数值999999输出:输出:长方体的数和长方体的数和1 1、“直译直译”枚举过程枚举过程forfor x11 to n do 枚举所有可能的平面枚举所有可能的平面 forfor x21 to n do forfor y11 to n do forfor y21 to n do forfor z11 to n do 枚举所有可能的上平面和下底
14、面枚举所有可能的上平面和下底面 forfor z21 to n do 考察状态(考察状态(x1,y1,z1,x2,y2,z2););立方体问题考考察察状状态态(x1,y1,z1,x2,y2,z2)的的任任务务是是计计算算长长方方体体的的体体积积,并并调调整整最最优优解解。设设map为为立立方方体体对对应应的的三三维维矩矩阵阵;sum为为当当前前长长方方体体的的体体积积;best为为最最优优解解。考考察察过过程程如下如下 sum00;for for xxx1 1 to x2 do 计算长方体的体积计算长方体的体积 forfor yyy1 1 to y2 do forfor zzz1 1 to z
15、2 do sumsum+mapxsum+mapx,y y,zz;调整最优解调整最优解 if sumbest then bestsum if sumbest then bestsum;这个算法相当粗糙,枚举状态的费用为这个算法相当粗糙,枚举状态的费用为O O(n n9 9)2 2、从减少重复计算入手、从减少重复计算入手记记录录先先前前考考察察的的结结果果。在在统统计计长长方方体体2时时,只只要要将将长长方方体体1的的统统计计结结果果加加上上长长方方体体3就就可可以以了了,而而不必按上述算法那样重新进行计算。不必按上述算法那样重新进行计算。forfor x11 to n do 枚举所有可能的水平面
16、枚举所有可能的水平面 forfor x21 to n do forfor y11 to n do forfor y21 to n do forfor z11 to n do 枚举上平面的枚举上平面的z轴坐标轴坐标 begin sum00;长方体的体积初始化长方体的体积初始化 forfor z21 to n do 枚举下底面的枚举下底面的z轴坐标轴坐标 考察状态(考察状态(x1,y1,z1,x2,y2,z2););end end;forfor考察过程改为考察过程改为 forfor xxx1 1 to x2 do 计算长方体的体积计算长方体的体积 forfor yyy1 1 to y2 do su
17、msum+mapxsum+mapx,y y,z z2 2;if sumbest then bestsumif sumbest then bestsum;调整最优解调整最优解 由于利用了计算出的结果,整个算法的时间复杂度降为由于利用了计算出的结果,整个算法的时间复杂度降为O O(n n8 8)。)。3 3、提取恰当的信息、提取恰当的信息上述考察实际上求出z轴坐标为z2的平面中矩形(x1,y1,x2,y2)的数和。我们将这个数和记为value(a)value(A)=value(ABCD)+value(B)-value(BC)-value(BD)这就启发我们用另一种方法表示立方体的信息:设recx,
18、y,z表示z轴坐标为z的水平面中矩形(1,1,x,y)的数和。z轴坐标为z的水平面中左上角为(x1,y1)、右下角为(x2,y2)的矩阵的数和为recx2,y2,z+recx1,y1,z-recx2,y1,z-recx1,y2,zRecRec数组可以在输入数据的同时计算数组可以在输入数据的同时计算fillchar(recfillchar(rec,size(rec)size(rec),0)0);recrec数组初始化数组初始化 forfor z1 to n do 逐层输入信息逐层输入信息 forfor x1 to n do 逐行输入逐行输入z平面的信息平面的信息 begin forfor y1
19、to n do 逐列输入逐列输入z平面上平面上x行的信息行的信息beginbegin read(mapx read(mapx,y y,z)z);输入输入z z平面上(平面上(x,yx,y)中的数)中的数 if(x=1)and(y=1)if(x=1)and(y=1)计算计算z z平面上以(平面上以(1 1,1 1)为左上角、()为左上角、(x,yx,y)为右下角的矩形的数和)为右下角的矩形的数和 then rec1then rec1,1 1,zmap1zmap1,1 1,zzelse if y=1 then recxelse if y=1 then recx,y y,zrecx-1zrecx-1
20、,n n,z+mapxz+mapx,y y,zz else recx else recx,y y,zrecxzrecx,y-1y-1,z+mapxz+mapx,y y,zz;end end;forfor readln readln;end end;forfor这样,考察过程就可以改为这样,考察过程就可以改为 sumsum+recx sumsum+recx2 2,y y2 2,z z2 2+recx+recx1 1,y y1 1,z z2 2-recx-recx2 2,y y1 1,z z2 2-recx-recx1 1,y y2 2,z z2 2;if sumbest then best if
21、 sumbest then bestsumsum;时间复杂度降为时间复杂度降为O O(n n6 6)。)。如如果果长长方方体体a的的数数和和是是负负数数,则则长长方方体体a的的计计算算结结果果废废弃弃,考考察察长长方方体体b-a。因因为为长长方方体体b的的数数和和=长长方方体体b-a的的数数和和+长长方方体体a的的数数和和,由由于于长长方方体体a的的数数和和为为负负,长长方方体体b-a的的数数和和一一定定大大于于等等于于长长方方体体b的的数数和和。由由此此可可见见,在在累累计计长长方方体体数数和和的的时时候候,只只要要由由上上而而下下地地枚枚举举长长方方体体下下底底面面的的z轴轴坐标即可。设坐
22、标即可。设total(z)以以z轴轴坐坐标标为为z的的平平面面为为下下底底面面的的长长方方体的最大数和体的最大数和forfor x11 to n do 枚举所有可能的子平面枚举所有可能的子平面 forfor x21 to n do forfor y11 to n do forfor y21 to n do begin total00;长方体以长方体以(x(x1 1,y,y1 1)为左上角为左上角,(x,(x2 2,y,y2 2)为右下角)的最大数和初始化为右下角)的最大数和初始化 for for z1 to n do 枚举枚举长方体长方体b b下底面的下底面的z z轴坐标轴坐标 begin t
23、otalmaxtotaltotalmaxtotal,0+0+recx2,y2,z+recx1-1,y1-1,z-recx2,y1-1,z-recx-1-1,y2,z;计算以计算以z为下底面的长方体为下底面的长方体b的最大数和的最大数和 if total best then besttotaltotal;调整最优解调整最优解 end end;forfor end end;forfor这一改进使得考察的状态整数降为这一改进使得考察的状态整数降为O(nO(n5 5)子串子串给定一个由自然数串联而成的无限数列1234567891011121314(母串)求任意一个长度不超过200的数列(子串)在其中最
24、早出现的位置。分析:首先,由于母串可无限扩充,显然我们不可能把它全部生成出来。如果边生成母串,边判断所生成的数串是否包含给定的子串,即使是使用字符串处理中高效的KMP算法,耗费的工作量也是巨大的。1121314先枚举第1位1自然数1之后为2,3,母串中形如123与子串从第2位开始不符枚举前2位11自然数11之后为12,13母串中形如111213与子串从第3位开始不符考虑第2位开始12自然数12之前为11,末位与子串第1位相同,之后为13,14,母串中形如1314与子串匹配!如何优化呢?较好的方法是另辟蹊径:刚才我们枚举的是母串的每一位,不妨换一个角度,从子串着手。先来观察一些片断:123456
25、78910111213141516很自然得到算法:枚举子串所包含第一个完整的数a的位数La。假设a在母串的第k位出现(k=La)判断接下来由a生成的序列是否与子串吻合。如果吻合,则最优解的判断:(1)LaAns_k4跟据Ans_a及Ans_k计算出位数总时间复杂度约为O(n3),与之前的不可估量相比有了本质性提高。第4步可通过多种途径求得,这里不作介绍。由于其中牵涉到许多高精度的计算及字符串处理,要求我们细致认真。小结充分挖掘题目特性是解决本题的关键。得以使枚举这类看似低效率的方法得到较好的运用。同时细致全面的考虑问题也是必不可少的。宽度优先遍历算法框架从某个未被访问的顶点从某个未被访问的顶点
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 枚举 搜索 动态 规划 试题 讲课
限制150内