dp基础之划分型划分最小划分次数

问题:给定一个字符串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

猜你喜欢

转载自blog.csdn.net/lerry13579/article/details/84192685