這個題,初學之時,老師教我們用分治演算法,分三路:在左邊子陣列、在右邊子陣列以及跨越中線,其實用動態規劃已經很簡單了,看狀態轉移方程就明白了:
\[dp[i] = \beginarr[i], & \quad i==0\\
max\, & \quad otherwise
\end
\]
def maximum_subarr(arr):
if not arr:
return none
dp = [0]*len(arr)
dp[0] = arr[0]
for i in range(1, len(arr)):
dp[i] = max(dp[i-1]+arr[i], arr[i])
return max(dp)
狀態轉移方程為:
\[dp[i][j] = \begindp[i-1][j-1], & \quad s1[i] == s2[j]\\
min\+1, & \quad otherwise
\end
\]注意邊界的情況:i、j是從1開始的,0表示空字串。
def edit_distance(s1, s2):
if len(s1) == 0:
return len(s2)
if len(s2) == 0:
return len(s1)
dp = [[0]*(len(s2) + 1) for _ in range(len(s1) + 1)]
for i in range(len(s1)+1):
for j in range(len(s2)+1):
if i == 0:
dp[i][j] = j
elif j == 0:
dp[i][j] = i
else:
if s1[i-1] == s2[j-1]:
dp[i][j] = dp[i-1][j-1]
else:
dp[i][j] = min(min(dp[i-1][j], dp[i][j-1]), dp[i-1][j-1]) + 1
return dp[len(s1)][len(s2)]
狀態轉移方程為:
\[dp[i][j] = \begindp[i-1][j-1]+1, & \quad s1[i] == s2[j]\\
0, & \quad otherwise
\end
\]最終的答案是整個dp陣列中的最大值。
def longest_common_substring(s1, s2):
if not s1 or not s2:
return 0
max_len = 0
dp = [[0]*(len(s2)+1) for _ in range(len(s1)+1)]
for i in range(1, len(s1)+1):
for j in range(1, len(s2)+1):
if s1[i-1] == s2[j-1]:
dp[i][j] = dp[i-1][j-1] + 1
if dp[i][j] > max_len:
max_len = dp[i][j]
else:
dp[i][j] = 0
return max_len
子串行可以不是連續的,所以,狀態轉移方程為:
\[dp[i][j] = \begindp[i-1][j-1]+1, & \quad s1[i] == s2[j]\\
max\, & \quad otherwise
\end
\]
def longest_common_subseq(s1, s2):
if not s1 or not s2:
return 0
m = len(s1)
n = len(s2)
dp = [[0]*(n+1) for _ in range(m+1)]
for i in range(1, m+1):
for j in range(1, n+1):
if s1[i-1] != s2[j-1]:
dp[i][j] = max(dp[i-1][j], dp[i][j-1])
else:
dp[i][j] = max(max(dp[i-1][j-1]+1, dp[i][j-1]), dp[i-1][j])
return dp[m][n]
動態規劃專題
多階段過程轉化為一系列單階段問題,利用各階段之間的關係,逐個求解,創立了解決這類過程優化問題的新方法 動態規劃 個人的理解 就是處於當前決策時要依賴前面的已知情況,將看似 連續無統一標準解決方案 的問題分割成多個 可以商量的 的決策過程。商量就是依靠已知的情況覺得未知 那麼什麼問題才可以用到動態規劃...
動態規劃專題
例一 有一段樓梯有10級台階,規定每一步只能跨一級或兩級,要登上第10級台階有幾種不同的走法?1 include 2 include 3 include 4 include5 using namespace std 6int solution int n 遞迴做法713 int dp 11 14in...
動態規劃專題
在 acm 能夠開展之前,必須準備預算,並獲得必要的財力支援。該活動的主要收入來自於 irreversibly bound money ibm 思路很簡單。任何時候,某位 acm 會員有少量的錢時,他將所有的硬幣投入到小豬儲錢罐中。這個過程不可逆,因為只有把小豬儲錢罐打碎才能取出硬幣。在足夠長的時間...