dp基礎之劃分型劃分最小劃分次數
阿新 • • 發佈:2018-11-19
問題:給定一個字串S[0,..n-1],最少劃分幾次使得每個子串都是迴文串
確定狀態:最優策略中最後一段迴文串是S[j...n-1]
需要知道S前j個字元[0...j-1]最少可以劃分成幾個迴文串
子問題:
設:S前i個字元[0...i-1]最少可以劃分成f[i]個迴文串
f[i] = min{f[j]+`1 | S[j...i-1]是迴文串}
{S前j個字元可以最少劃分成幾個迴文串+最後一段迴文串}
初始條件:
f[0] = 0,前0個即空串是0
計算順序:f[0]...f[n]
判斷迴文串:
分為奇數長度迴文串和偶數長度迴文串。
對每個字元進行列舉,兩邊擴充套件,建立一個二維陣列,huiwen[i][j]表示字串S[i...j]是否是迴文串,1表示是,0表示不是
程式碼及註釋如下:
import sys def min_huiwen(S): n = len(S) if n == 0: return 0 #建立一個二維陣列huiwen[i][j]表示字串S[i...j]是否是迴文串,初始為0,即都不是迴文串 huiwen = [[0 for i in range(n)] for j in range(n)] #賦值huiwen[][j] for t in range(n): #對於奇數長度迴文串,從t向兩頭拓展 i = t j = t while i>=0 and j<n and S[i] == S[j]: huiwen[i][j] = 1 i -= 1 j += 1 #對於偶數長度迴文串 i = t j = t+1 while i>=0 and j<n and S[i] == S[j]: huiwen[i][j] = 1 i -= 1 j += 1 #S前i個字元[0...i-1]最少可以劃分成f[i]個迴文串 f = [sys.maxsize for i in range(n+1)] f[0] = 0 for j in range(1,n+1): #f[i] = min{f[j]+`1 | S[j...i-1]是迴文串} for i in range(j): if huiwen[i][j-1] == 1: f[j] = min(f[i]+1,f[j]) #劃分次數是個數-1 return f[n]-1 S = ['a','a','b'] print(min_huiwen(S)) #結果:1