一些本章的习题的解法简答及伪码。
15.1-5 斐波那契数的子问题图。每个斐波那契数与前两个斐波那契数有关。所以有N个顶点,2*(N-2)条边。
15.2-4 矩阵链乘法的子问题图。N个矩阵的子问题是N-1对,所以共有(N-1)*N/2与N*(N-1)*(N-2)/2条边。
15.3-6 外币兑换问题。必须是不重复的兑换。可以做一个集合S={D1, D2, D3…}代表兑换序列,sn=r12*r23*…*rn代表最终兑换金额,那么开始是{D1, Dn},然后每次加入一个新元素i,找到最佳的si。可以证明新加入的元素不改变原来序列的顺序,只需要找一个最佳位置插入。那么每次的子问题就是for(i=2 to n) find_best_sn。
15.4-5。最长单调子序列。若已知到第i位为止的最长单调子序列,考察第i+1位a[i+1],会发生什么情况?它能够续接到到那些末位<a[i+1]的子序列中,从而将这些子序列加长1。令A[i],B[i]分别代表S截至到第i位的最长单调子序列的长度和构成最长单调子序列的A[i]的前驱在S中的位置。
longest(S){
for(i = 1 to S.n){
for(j= 1 to i){
if(S[i]>S[j]){ A[i]=max(A[i], A[j]+1); if(A[i] changed) B[i]=j;}
}
}
}
最差运行时间是O(n^2)。最长单调子序列的元素个数是A[n]即A[]的最后一项,B[i]是第i位作为最长单调子序列的最后一项时,其前驱项在S的位置。最长单调子序列是L: