葫芦岛23点
钢条切割
给定一段长度为n英寸的钢条和一个价格表p_i,求切割钢条方案,使得销售收益r_s最大。如果长度为n英寸的钢条的价格p_n足够大,最优解可能就是完全不需要切割。
长度为n英寸的钢条共有 2¯(n-1)
种不同的切割方案,因为在距离钢条左端i英寸处总是可以选择切不切,如果要求按切割数量非递减的顺序切割,切割方案会少很多,近似等于e¯(x√(2n/3))/4n√3
,但仍远远大于任何n的多项式。
应用递归式r[n]=max(1<=i<=n)->(p[i]+r[n-i])
将一个指数时间的解转化为一个多项式时间的解,时空权衡【time-memory trade-off】。
矩阵链乘法
1 | MATRIX-MULTIPLY(A,B) |
给定n个矩阵的链,矩阵A_i的规模为p_i-1*p_i(1<=i<=n),求完全括号化方案,使得计算A_1A_2…A_n所需标量乘法次数最少。完全括号化【fully parenthesized】指的是单一矩阵或者是两个完全括号化的矩阵乘积链的积,且已外加括号。
穷举所有括号化方案会得到递归式P(n)={1若n=1|∑k=1to(n-1)->P(k)P(k-n)若n>=2}
,Ω(2¯n)
相似的递归公式产生的序列为卡特兰数【catalan numbers】,这个序列的增长速度为Ω(4¯n/n¯(3/2))。
应用递归式m[i,j]={0若i=j|min(i<=k<j)->(m[i,k]+m[k+1,j]+p_(i-1)p_kp_i)若i<j}
完成Ω(n¯2)
的算法。
构造最优解
1 | PRINT-OPTIMAL-PARENS(s,i,j) |
最长公共子序列
给定两个序列X和Y,如果Z既是X的子序列,也是Y的子序列,那么称Z是X和Y的公共子序列【common subsequence】。以Z的长度作为X和Y的相似度,那么相似度最高的序列被认为是最长公共子序列【longest common subsequence】。
应用递归式c[i,j]={0若i=0或j=0|c[i-1,j-1]+1若i,j>0且x_i=y_j|max(c[i,j-1],c[i-1,j])若i,j>0且x_i≠y_i}
。
构造最优解
1 | PRINT-LCS(c,X,i,j) |
最长上升子序列
应用递归式c[i]={max(1<=j<i)->(c[j]+1)若x[i]>x[j]}
完成O(n¯2)
的算法。
一个长度为i的候选子序列的尾元素至少不比一个长度为i-1候选子序列的尾元素小。可得O(nlgn)
算法。
1 | l[1]=x[1] |
最优二叉搜索树
假定我们正在设计一个程序,实现英语文本到法语的翻译。对英语文本中出现的每个单词,我们需要查找对应的法语单词。为了实现这些查找操作,可以创建一棵二叉搜索树,将n个英语单词作为关键字,对应的法语单词作为关联数据。由于文本中的每个单词都要进行搜索,我们希望花费在搜索上的总时间尽量少。
通过红黑树或其他平衡搜索树结构,我们可以假定每次搜索时间为O(lgn) 。但由于单词出现的频率是不同的,像“the”这种频繁使用的单词有可能位于搜索树中远离根的位置上,而像“machicolation”这种很少使用的单词可能位于靠近根的位置上。这样的结构会减慢翻译的速度,因为二叉树搜索树中搜索一个关键字的权重是深度+1。我们希望文本中频繁出现的单词被置于靠近根的位置。在给定单词出现频率的前提下,我们应该如何组织一棵二叉搜索树,使得所有搜索操作访问的结点总数最少呢?
递归式e[i,j]={q_(i-1)若j=i-1|min(i<=r<=j)->(e[i,r-1]+e[r+1,j]+w[i,j])若i<=j}
。