习题答案
Posted sushauai
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了习题答案相关的知识,希望对你有一定的参考价值。
Permalink: 2013-05-07 09:51:00 by hyhx2008in clrs tags: clrs algorithm15.2-2
Q:请给出一个递归算法MATRIX-CHAIN-MULTIPLY(A,s,i,j),使之在给出矩阵序列<A1,A2,...,An>,和由MATRIX-CHAIN-ORDER计算出的表s, 以及下标i和j后,能得出一个最有的矩阵链乘法。(初始调用为MATRIX-CHAIN-MULTIPLY(A,s,1,n))。
A:模仿PRINT-OPTIMAL-PARENS(s,i,j)即可。伪代码:
MATRIX-CHAIN-MULTIPLY(A,s,i,j) if i=j then return Ai; else return MATRIX-CHAIN-MULTIPLY(A,s,i,s[i,j])*MATRIX-CHAIN-MULTIPLY(A,s[i,j]+1,j);
15.4-5
Q:请给出一个O(n^2)时间的算法,使之能找出一个n个数的序列中最长的单调递增子序列。
A:这里给出两种算法。
方法1:假设这n个数存在数组X中,首先将这n个数按单调递增的顺序排序,将排好序的数组存于Y中。 然后通过计算X和Y的最长公共子序列即可找到答案。
方法2:直接利用动态规划的思想。设f(i)为以第i个数结尾的最长单调递增子序列的长度, 则f(i)=max(f(k)+1, 其中k<i且X[k]<X[i]),如果在1到i-1内找不到符合条件的k,那么f(i)就只能等于1了。 为了方便最后构造最长子序列,还需要另一个数组pre[i]存储以第i个数结尾的最长递增子序列的倒数第2个数。 伪代码:
LIS-Length(X) max = 0; max_i = 0; f[1..n] = 1; pre[1..n] = -1; for i = 1 to n do for k = 1 to i-1 do if X[k]<X[i] and f[k]+1 > f[i] then f[i] = f[k] + 1; pre[i] = k; for i = 1 to n do if f[i] > max then max = f[i]; max_i = i return max; LIS-print(i) if pre[i] != -1 LIS-print(pre[i]); print i;
15.4-6
Q:请给出一个O(nlgn)时间的算法,使之能找出一个n个数的序列中最长的单调递增子序列。 (提示:观察长度为i的一个候选因子序列的最后一个元素,它至少与长度为i-1的一个候选子序列的最后一个元素一样大。通过把候选子序列与输入序列相连接来维护它们)。
A:这个提示看了好几遍也没有看懂说的是什么意思,大概是翻译的问题吧。总之需要将算法改进到O(nlgn)的复杂度。 自己想不到好的办法,百度了一下,想法还是挺巧妙的,用一个数组D[len]记录len长的递增子序列的最小末尾元素。 只需要从1到n一遍扫描中间加上二分查找,可以得到O(nlgn)的算法。这里不详细讨论,附上一个连接:
以上是关于习题答案的主要内容,如果未能解决你的问题,请参考以下文章