算法作业.docx
- 文档编号:9207552
- 上传时间:2023-02-03
- 格式:DOCX
- 页数:31
- 大小:2.84MB
算法作业.docx
《算法作业.docx》由会员分享,可在线阅读,更多相关《算法作业.docx(31页珍藏版)》请在冰豆网上搜索。
算法作业
Chapter1
1.证明:
n个矩阵连乘,加括号的方法数是n阶Catalan数:
证:
设矩阵连乘M1M2┅MiMi+1┅Mn
考虑最后一次乘法的所在位置:
可以是
M1(M2┅MiMi+1┅Mn)也可以是
(M1M2)(M3┅MiMi+1┅Mn)也可以是
(M1M2┅Mi)(Mi+1┅Mn)也可以是
(M1M2┅MiMi+1┅Mn-1)Mn
即最后一次乘法的所在位置共有n-1个,按这n-1个位置分类:
设n个矩阵连乘加括号方法数为an,则a1=1,a2=1,a3=2,……
类型M1(M2┅MiMi+1┅Mn)中的方法数共有an-1种;
类型(M1M2)(M3┅MiMi+1┅Mn)中的方法数共有an-2种;
……
类型(M1M2┅Mi)(Mi+1┅Mn)中的方法数共有aian-i种;
……
类型(M1M2┅MiMi+1┅Mn-1)Mn中方法数共有an-1种
故an为上述n-1类的总和:
an=an-1+an-2+┅+aian-i+┅+an-1
令a0=0,则上式可写为an=a0an+a1an-1+a2an-2+……+aian-i+……
+an-2a2+an-1a1+ana0——恰好是n阶Catalan数所满足的方程。
2.证明:
把n(n>=3)边凸多边形划分成n-2个三角形的方法数是
n-1阶Catalan数:
证:
把n边凸多边形(n≥3)划分成n-2个三角形,可按如下方式考虑:
设n+1边凸多边形的三角形划分方法数为an+1并令bn=an+1(n≥2)由于n+1边凸多边形的每条边必在某个三角形中,故点1与点n+1的连线P也必在某个三角形中,其所对的顶点可以是点2,或点3,┅或点k,或点k+1,┅或点n。
以连线P所对的顶点进行分类:
对点2,点3,┅,点n。
当连线P所对的顶点是点2时,点n+1,点1,点2构成的三角形已确定,而由点2,点3,┅,点n,点n+1构成另一个n边凸多边形,故属于此类(连线P对点2)的三角形划分方法数为an=bn-1;当连线P所对的顶点是点3时,点n+1,点1,点3构成的三角形已确定(此时点1,点2,点3构成的三角形也已随之确定),而由点3,点4,┅,点n,点n+1构成一个n-1边凸多边形,属于此类的三角形划分方法数为an-1=bn-2;┅┅,一般地,
当连线P所对的顶点是点k时,点n+1,点1,点k构成的三角形已确定,该三角形的一边是由点1,点2,┅,点k构成的.k边凸多边形(该k边凸多边形三角形划分方法数为ak=bk-1);而该三角形的另一边是由点k,点k+1,┅,点n,点n+1构成的
n-k+2边凸多边形(该n-k+2边凸多边形三角形划分方法数为an-k+2=bn-k+1);故属于此类的三角划分方法数为bk-1*bn-k+1
当连线P所对的顶点是点k+1时,点n+1,点1,点k+1构成的三角形已确定,该三角形的一边是由点1,点2,┅,点k,点k+1
构成的k+1边凸多边形
(该k+1边凸多边形三角形划分方法数为ak+1=bk);
而该三角形的另一边是由点k+1,┅,点n,点n+1构成的
n-k+1边凸多边形(该n-k+1边凸多边形三角形划分方法数为an-k+1=bn-k);故属于此类的三角划分方法数为bk*bn-k
┅┅,
最后,当连线P所对的顶点是点n时,
当连线P所对的顶点是点n时,点n,点n+1,点1构成的三角形已确定,该三角形的一边是由点1,点2,┅,点n构成的n边凸多边形,故属于此类的三角形划分方法数为an=bn-1;
按连线P所对的顶点进行分类后得各类方法数:
对点2为bn-1,对点3为bn-2,┅,对点k为bk-1*bn-k+1,对点k+1为bk*bn-k,┅,对点n为bn-1;故总和为bn-1+bn-2+┅+bk-1*bn-k+1+bk*bn-k+┅+bn-1;由于
b0,b1均无定义(而b2=a3=1为凸3边形即三角形划分方法数);
故定义b0=0,b1=1,于是n+1边凸多边形三角划分方法数an+1即
bn=b0bn+b1bn-1+b2bn-2+┅+bk-1*bn-k+1+bk*bn-k+┅+bn-1b1+bnb0
且边界条件有:
b0=0,b1=1,b2=1,刚好满足n阶Catalan数条件
故bn是n阶Catalan数。
因此n边凸多边形三角划分方法数an即bn-1为n-1阶Catalan数。
3.设有n个实数a1 试证明: 以a1,a2,…,an为节点构成的不相同的n节点二叉树的棵数为n+1阶Catalan数: 证: 设不相同的n节点二叉树的棵数为bn。 显然b1=1,b2=2。 a1,a2,…,an各节点均可作为n节点二叉树的根。 按根节点的不同把n节点二叉树分为n类: 以a1为根,此时其左子树必为空,此时其右子树中的节点恰有n-1个,该右子树的不同构造方法数为bn-1,因此以a1为根的不同n节点二叉树数目为bn-1。 以a2为根,此时其左子树中有且仅有a1,即只有一种情况;而右子树中的节点恰有n-2个,该右子树的不同构造方法数为bn-2,因此以a2为根的不同n节点二叉树数目为bn-2.以a3为根,此时其左子树中恰有a1和a2,其不同构造方法数为b2;而右子树中的节点恰有n-3个,该右子树的不同构造方法数为bn-3,因此按乘法原理,以a3为根的n节点二叉树数目为b2bn-3。 ……以ak为根,此时其左子树中有a1。 。 。 ak-1,其不同构造方法 数为bk-1;而右子树中的节点有n-k个,该右子树的不同构造,方法数为bn-k,因此按乘法原理,以ak为根的n节点二叉树数目为bk-1bn-k。 …… 以an为根,此时其右子树必为空,(右子树中的节点值均大于根节点值)此时其左子树中的节点恰有n-1个,该左子树的不同构造方法数为bn-1,因此以an为根的不同n节点二叉树数目为bn-1。 故总的方法数bn=bn-1+bn-2+b2bn-3+…+bk-1bn-k+…+bn-1 令ck+1=bk(k≥1),有cn+1=cn+cn-1+c3bn-2+…+ckcn-k+1+…+cn 由于c2=b1=1,再令c1=1,c0=0。 于是有 cn+1=c0cn+1+c1cn+c2cn-1+c3bn-2+…+ckcn-k+1+…+cnc1+cn+1c0 恰好是n+1阶Catalan数的非线性递归方程。 4.证明: n个数据元素进出栈的方法数是n+1阶 Catalan数: 证: 考虑最后一个出栈的元素: 可以是第一个进栈的元素,如进进进出出出(n=3时) 也可以是第二个进栈的元素,如进出进进出出(n=3时) ┅, 也可以是第k个进栈的元素, ┅也可以是第n个(最后一个)进栈的元素, 如进进出出进出(n=3时) 计算方法: 按最后一个出栈的元素分类计算,再把各类总加。 设n个数据元素进出栈方法数为an。 第1类: 最后一个出栈的元素是第1个进栈的元素: 第1个元素进栈后一直未动,等其后的n-1个元素进出栈执行完毕后才出来,这n-1个元素进出栈方法数为an-1 第2类: 最后一个出栈的元素是第2个进栈的元素: 第2个元素最后出栈,说明第1个元素在第2个元素进栈前已经出栈,之后第2个元素进栈且一直未动,直到其后的n-2个元素进出栈执行完毕才出来,这n-2个元素进出栈方法数为an-2 第3类: 最后一个出栈的元素是第3个进栈的元素: 第3个元素最后出栈,说明第1、第2个元素在第3个元素进栈前已经出栈,之后第3个元素进栈且一直未动,直到其后的n-3个元素进出栈执行完毕才出来,2个元素进出栈方法数为a2而后n-3个元素进出栈方法数为an-3,此类方法数为a2an-3。 ┅ 第k类: 方法数为ak-1an-k。 ┅第n类(最后进栈元素最后出)为an-1, 得an=an-1+an-2+a2an-3+…+ak-1an-k+…+an-1 令ck+1=ak(k≥1), 有cn+1=cn+cn-1+c3bn-2+…+ckcn-k+1+…+cn 由于c2=a1=1,再令c1=1,c0=0。 于是有 cn+1=c0cn+1+c1cn+c2cn-1+c3bn-2+…+ckcn-k+1+…+cnc1+cn+1c0 可知总的方法数为n+1阶Catalan数。 5.用生成函数法求解变系数二阶齐次递归方程: (n-1)an=(n-2)an-1+2an-2,边界条件是: a0=0,a1=1。 解: 据此可算出a2=0,a3=1,且有(n-1)an-(n-2)an-1=2an-2。 设A(x)= 则A(x)=x+a3x3+a4x4+···=x(1+a3x2+a4x3+···) 令B(x)=1+a3x2+a4x3+···,则B(x)=A(x)/x, =2a3x+3a4x2+4a5x3+···, x =2a3x2+3a4x3+4a5x4+···, ∴ -x =2a3x+(3a4-2a3)x2+(4a5-3a4)x3+···, =2a3x+2a2x2+2a3x3+2a4x4+··· (∵(n-1)an-(n-2)an-1=2an-2,a3=1,a2=0。 ) ∴ -x =2x+2a3x3+2a4x4+··· =2x(1+a3x2+a4x3+···) =2xB(x) 即 (1-x)=2xB(x),于是可得 = =-2+ (此处注意由于 ,故有 ) 对上述等式两边作[0,x]上的定积分,由于B(0)=1,故有 LogB(x)=-2x-2Log(1-x) ∴B(x)= B(x)的幂级数展开为 ∵A(x)=xB(x) ∴an= (n 1) 解: 解: Chapter2 解: 最多 7次比较的過程如下: abcde 1: ab比較,如a>b 2: cd比較,如c>d 3: ac比較,如a>c。 此時可得: a>c>d且a>b 4: 由上a>c>d,e的位置需要2次比較即可確定。 e先和中位數c比較,如c>e 5: e再和d比較,如e>d。 此時可得acde的順序: a>c>e>d 6: 因b已經和a比較過,所以下麵隻需要考慮b和ced間的順序。 c>e>d,要確定b的位置3次比較即可。 先和中位數e比較 7: b和e比較之後根據大小再和c或d比較,即可得出bcde四個數的順序,也就排出了abcde5個數的順序。 解: 解: 假设同时又5个点存在于PL,那么必然同时有两个点存在于左边的四个小正方形中的一个,而小正方形的边长为σ/2,则这两个点之间的距离肯定大于0而小于√2σ/2,而已知两个点之间的最小距离是σ,所以这与已知矛盾顾假设不成立。 Chapter3 反证法: 假设二分搜索树中存在一棵节点编号不连续的子树 如图所示: 这棵树节点编号不连续出现,那么节点 在遇到树根12时,应当放在其左边,而不是右边,这与二叉搜索树的性质矛盾,因此假设不成立,原命题二分搜索树任何一棵子树中结点的编号都是连续的成立。 反证法: 假设最优树中的一棵子树不是一棵最优树 据假设最优树A的一棵子树B不是最优树,那么必然存在一棵与B含相同节点但最优树C,那么将C替换B,可以得到一棵比A还要优的最优树A’,这与A是最优树矛盾,所以假设不成立,原命题最优树中的任何一棵子树,也必然是关于子树中结点的最优树是正确的。 解: 1)证明: 设是一个最优调度,且在P1上安排的加工是有间断的。 则我们可以把所有在P1上出现间断处的任务的开始加工时间提前,使得在P1上的加工是无间断的;而在P2上仍按原先的安排。 把这样调整之后的调度记作为’。 由于在调度’下,任何一个任务在P1上加工的结束时间不晚于在调度下的结束时间,故调度’不会影响在P2上进行加工的任何一个任务的开始时间。 由于调度’在P1上的结束时间不晚于调度,在P2上的结束时间与调度相同,而又是最优调度,所以’也是最优调度。 由此我们得到: 一定有一个最优调度使得在P1上的加工是无间断的。 另外,也一定有一个最优调度使得在P2上的加工空闲时间(从0时刻起算)为最小,同时还满足在P1上的加工是无间断的。 2)证明: 假设一个最优调度满足在P1上的调度是无间断的,但在P2上的空闲时间不为最小。 那么必然存在另外一个调度’在P1上的调度是无间断的,但在P2上的空闲时间比小,并且在P2上的其他调度时间两者是相等的,那么’的总时间就比小,因此就不是最优调度,与题意矛盾,因此假设不成立。 证明: 如图所示,显然T1>T2,且第一种调度方法中,P2上的加工次序与P1不同. 因为在P2上要先执行T22,那么在P1上还得先执行T21,而此时,T11已执行完毕,但T12却不能执行(因为要保证次序不同),因此P2空等了一个T12的时间,因此若P2上的加工次序与P1不同,必然增加时间,若某些任务没有T11,那么可能时间不变。 Chapter4 解: 用树结构来表示集合: 仅在树根处记录集合的名字。 初始时每个结点是一棵单节点树,作集合合并时,让结点少的树A的根指向结点多的树B的根(结点数相同时可选其中任一个根作为新的根),这样就完成了集合的合并。 故合并可以在O (1)时间里面完成。 Name Count Father 每个结点i的形式为: Name[i]: 以结点i为根的子树原有的名称。 但只有含结点i的树的根结点处的Name才是当前正确的集合名。 Count[i]: 以结点i为根的子树中元素的个数。 但只有含结点i的树的根结点处的Count才是当前集合正确的元素个数。 Father[i]: 结点i的父结点的编号。 结点i是根结点时,则该域为0。 此外,还有一个数组Root记录每个集合的根节点编号,即Root[k]为: 名为k的树(集合)的根结点编号。 这样的处理,使得Union可以在O (1)时间里完成,但Find时间将会增多,在最坏情况下,执行1条Find指令需要O(Logn)。 于是执行O(n)条Union-Find指令仍需要O(n*Logn)。 意到: 执行Find[i]指令时,必然会形成一条从结点i到根的路径P,如果我们让该路径P上的所有非根节点均指向根(路径压缩),这样,下一次对该路径上的结点再执行Find指令时,查找时间就会变短(因各结点已直接指向根节点)。 为使上述路径压缩工作能够执行得更顺利,对前述合并算法进行适当调整,新合并算法的思路如下: 假定集合名在1…n之间。 用树的高度字段取代原Count字段(树中元素个数); 合并后新集合的名字用原先树高值大的集合的名字 (即不指定外部名), 即让原先树高值小的树的根,指向树高值大的树的根。 这样,Union不做各元素的所属集合改名,Find只与树的高度有关。 该算法只用2个数组: P[i]: 若i为根结点,则P[i]=i。 若i不是根结点,则P[i]是i的父结点的编号。 rank[i](秩): 在指令序列 中删去Find指令,得到只含Union指令的新序列 rank[i]是执行 (即未经压缩)时,以结点i为根的子树的树高。 (若在执行中有Find指令,则会对树进行压缩, 所以rank[i]≥结点i实际的深度。 ) 带路径压缩的递归程序Find(i): (注意: 应尽可能避免使用全局变量, 虽然此处为突出重点p不是入口参数) ifi p[i]/*i不是根*/ thenp[i] Find(p[i]); returnp[i]; 注意: Find操作既不改变树的大小 (仅仅是将指针改一下), 也不改变rank的值。 但很有可能会改变树高。 Union(i,j)/*i,j可以是任意结点,不一定是根结点*/ a Find(i)/*a是含结点i的树的根结点编号*/ b Find(j)/*b是含结点j的树的根结点编号*/ ifa=breturna;/*i,j在同一个集合中,无需进行Union*/ ifrank[a]>rank[b]/*根结点为a的树‘深’,b指向a*/ then{p[b] a;returna;} else{p[a] b;/*根结点为b的树‘深’或相等,a指向b*/ ifrank[a]=rank[b]thenrank[b]增1;returnb;} 注意,rank的改动只在: 两rank相等时,新根结点rank才被增1。 在Union算法中,除了2个Find以外,其余的工作量是O (1)。 所以主要的工作量是花在Find指令的执行上,所以,根据平摊分析的聚集方法,O(n)条Unoin-Find指令的时间复杂度,主要取决于O(n)条Find指令(其余工作的总和只有O(n))。 用平摊分析的聚集方法, 把O(n)条Find指令的耗费分为三类: O(n)条Find指令的根费用, O(n)条Find指令的组费用, O(n)条Find指令的路径费用。 三项费用总加起来,有O(n)+O(n*G(n))+O(n*G(n))=O(n*G(n))于是可得结论: 如果合并是把小集合并入大集合,且执行Find指令时实施路径压缩,则执行O(n)条Unoin-Find指令的时间复杂度为O(n*G(n));若执行Find指令时不实施路径压缩,则执行O(n)条Unoin-Find指令的时间复杂度为O(nLogn)。 实施路径压缩使算法达到近似线性的水平。 用上述所给算法执行O(n)条Unoin-Find指令时,对于任意的c,都存在一个特殊的Unoin-Find指令序列,使得执行该序列的时间复杂度>cn,即算法在最坏情况下不是线性的。 解: find_depth(i) 返回 D 森林根节点编号和 i 节点深度 ,它 的实现如下所示,要注意几点: 1. 如果是根节点 , 一个参数是 D 森林根节点编号,另一个为 weight 为 0 2. i 的深度 =weight[i]+i 的父节点的 weight+i 的父节点的父节点的 weight+...+ 一直到 D 森林根节点 3.第一次 find 需要经过路径压缩 O(n) 次需要 O(n*G(n)) //返回D森林根节点编号和i节点深度 privatePairfind_depth(inti){ if(i==point[i])//如果是根节点,一个参数是D森林根节点编号,另一个为weight为0 returnnewPair(i,0);//返回根节点的编号和i节点的新权值 Pairpair=find1(i);//获得根节点编号 introotId=pair.first;//获得i节点的新权值(=weight[i]+i的父节点的weight+i的父节点的父节点的weight+...+D森林k-1节点) intiNewWeight=pair.second;//返回根节点编号和i节点深度 //深度=weight[i]+i的父节点的weight+i的父节点的父节点的weight+...+一直到D森林根节点 //第一次find需要经过路径压缩O(n)次需要O(n*G(n)) returnnewPair(rootId,iNewWeight+weight[rootId]); } 解: link(v,r)将以r链接到v,合并两棵树,它的实现如下所示,但同样也要注意几点: 1.首先要获得D森林v的根节点编号和D森林r的根节点编号以及v节点深度 2.如果count[rootOfV]>=count[rootOfR]则将r所在D森林中的根rootOfR(r')指向v所在D森林中的根rootOfV(v') 3.新weight[rootOfR]-旧weight[rootOfR]+weight[rootOfV]=depth(v)+1 4.如果count[rootOfV] 5.需要修改两处地方: 新weight[rootOfR]-旧weight[rootOfR]=depth(v)+1和旧weight[rootOfV]+新weight[rootOfV]+weight[rootOfR]=depth[v] //link(v,r)将以r链接到v,合并两棵树 publicvoidlink(intv,intr){ //返回D森林v的根节点编号和v节点深度 PairpairV=find_depth(v); //返回D森林r的根节点编号和r节点深度 PairpairR=find_depth(r); //D森林v的根节点编号 introotOfV=pairV.first;//D森林v节点深度 intdepthV=pairV.second; //D森林r的根节点编号 introotOfR=pairR.first;//D森林r节点深度 intdepthR=pairR.second; if(count[rootOfV]>=count[rootOfR]){ count[rootOfV]+=count[rootOfR]; //r接到v上时候深度发生变化因此需要修改D森林r的根的权 //-旧weight[rootOfR]+新weight[rootOfR]+weight[rootOfV]=depth(v)+1 weight[rootOfR]=depthV+1+weight[rootOfR]-weight[rootOfV]; //将r所在D森林中的根rootOfR(r')指向v所在D森林中的根rootOfV(v') point[rootOfR]=rootOfV; }else{ count[rootOfR]+=count[rootOfV]; //r接到v上时候深度发生变化因此需要修改D森林r的根的权 //新weight[rootOfR]-旧weight[rootOfR]=depth(v)+1 weight[rootOfR]=depthV+1+weight[rootOfR]; //D森林中,rootOfV(书中是v')的根发生变化,变为rootOfR(书中是r') //旧weight[rootOfV]+新
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 算法 作业