本類的狀態是基礎的基礎,大部分的動態規劃都要用到它,成爲一個維。算法
最長不降低子序列定義:從序列中選出若干個數組成一個新的序列,不改變他們的隊伍的順序,要求新的序列裏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。