本类的状态是基础的基础,大部分的动态规划都要用到它,成为一个维。算法
最长不降低子序列定义:从序列中选出若干个数组成一个新的序列,不改变他们的队伍的顺序,要求新的序列里xi≤xi+1≤xi+1.....举个例子{4,6,5,7,3},最长不降低子序列就是{4,6,7}。数组
输入a[1,...,n] 输出:最长子序列优化
时间复杂度:O(n^2)spa
【矩阵链乘】设计
假设:m[i, j] = 计算Ai~j的最小乘法数; A1 ... AkAk+1 .... An 是优化解(k其实是不可预知)指针
输入:<A1, A2, ..., An>, Ai是矩阵 输出:计算A1 x A2 x ... x An的最小代价方法 Matrix-Chain-Order(p) n=length(p)-1; FOR i=1 TO n DO m[i, i]=0; FOR l=2 TO n DO /* 计算地l对角线*/ FOR i=1 TO n-l+1 DO j=i+l-1; m[i, j]= ∞; FOR k←i To j←1 DO /* 计算m[i,j] */ q=m[i, k]+m[k+1, j]+ pi-1pkpj IF q<m[i, j] THEN
m[i,j]=q; s[i,j]=k; Return m and s.
Print-Optimal-Parens(s, i, j) //构建最优解,输出A1-n的优化计算顺序 IF j=i THEN Print “A”i; ELSE Print “(” Print-Optimal-Parens(s, i, s[i, j]) Print-Optimal-Parens(s, s[i, j]+1, j) Print “)”
【三角剖分】code
输入:C>0, wi>0, vi>0, 1≤ i≤n
输出:(x1, x2, …, xn), xi∈{0, 1}, 知足 ∑1≤i≤nwi xi ≤C, ∑1≤i≤nvi xi 最大blog
For j=0 To min(wn-1, C) Do m[n, j] = 0; For j=wn To C Do m[n, j] = vn; For i=n-1 To 2 Do For j=0 To min(wi -1, C) Do m[i, j] = m[i+1, j]; For j=wi To C Do m[i, j]=max{m[i+1, j], m[i+1, j-wi]+vi}; If C<w1 Then m[1, C]=m[2, C]; Else m[1, C]=max{m[2, C], m[2, C-w1]+v1};
m(1, C)是最优解代价值,相应解计算以下: //构造优化解 If m(1, C) = m(2, C) Then x1 = 0; Else x1 = 1; 若是x1=0, 由m(2, C)继续构造最优解; 若是x1=1, 由m(2, C-w1)继续构造最优解.
输入:X = (x1,x2,...,xm),Y = (y1,y2,...yn) 输出:Z = X与Y的最长公共子序列 C[0:m,0:n]: C[i,j]是Xi与Yj的LCS的长度 B[1:m,1:n]: B[i,j]是指针,指向计算C[i,j]时所选择的子问题的优化解所对应的C表的表项 LCS-length(X, Y) m←length(X);n←length(Y); For i←0 To m Do C[i,0]←0; For j←0 To n Do C[0,j]←0; For i←1 To m Do For j←1 To n Do If xi = yj Then C[i,j]←C[i-1,j-1]+1;B[i,j]←“↖”; Else If C[i-1,j]≥C[i,j-1] Then C[i,j]←C[i-1,j]; B[i,j]←“↑”; Else C[i,j]←C[i,j-1]; B[i,j]←“←”; Return C and B. Print-LCS(B, X, i, j) IF i=0 or j=0 THEN Return; IF B[i, j]=“↖” THEN Print-LCS(B, X, i-1, j-1); Print xi; ELSE If B[i, j]=“↑” THEN Print-LCS(B, X, i-1, j); ELSE Print-LCS(B, X, i, j-1). Print-LCS(B, X, length(X), length(Y)) 可打印出X与Y的LCS。