对于一个动态编程问题,我想提出一个英语算法,备忘录表,最佳情况和递归调用来填充表以解决以下问题:
给出长度为n的字符串s,设计一种算法,输出最小的数字k,使得s = w1w2 . . . wk
其中每个wi是回文。换句话说,找到最小的k使得s可以写成k个回文的串联。有关回文的定义,请参见实践问题。例如,如果s = "add"
,则算法应该输出k = 2
,因为我们可以取w1 ="a"
和w2 ="dd"
。另一方面,如果s = "ada"
,则算法应输出k = 1。
我想出了以下算法:
Start
Declare variables s as string, n as integer, k as integer, i as integer.
Initialize k to 1
Read s
n<-length of string s
while i is less then n-1
if s[i]==s[i+1] then
k++
end if
display k
End
但是,我不确定如何提出记忆表,最佳情况以及填写该表所需的递归步骤。
答案 0 :(得分:0)
在动态编程中,备忘录表保存实际问题的子问题的答案。结合这些子问题答案,我们可以计算出实际问题的答案。
对于此问题,实际问题是为字符串k
找到最小的s
回文。因此,子问题可能类似于字符串k
的部分/子字符串的最小s
。为简化起见,如果我们知道子字符串s[0:i]
和s[i+1:length(s)-1]
的答案,那么我们可以计算出s[0:length(s)-1] = s[0:i] + s[i+1:length(s)-1]
的答案。
由此,我们可以轻松地形成我们的递归关系:
minKPalindrome(start, end) = minKPalindrome(start, i) + minKPalindrome(i+1, end), (start < i < end)
here, minKPalindrome(start, end) is function that return minimum k plaindrome for s[start:end] substring
可能的基本情况:
- if start > end , return answer 0
- s[start:end] is palindrome, so return answer is 1
递归算法:
memo[start][end] = contains answer for s[start:end]
minKPalindrome(start, end) {
if s[start:end] is palindrome {
return 1
}
if ans is already saved in memo[start][end] {
return memo[start][end]
}
memo[start][end] = end - start + 1 // set maximum possible answer
for i = start+1 to end-1 {
memo[start][end] = min( memo[start][end], minKPalindrome(start, i) + minKPalindrome(i+1, end))
}
return memo[start][end]
}
优化算法:
概括以前的递归关系:
minKPalindrome(s[start: end]) = minKPalindrome(s[start, i]) + minKPalindrome(s[i+1, end])
or,
minKPalindrome(s[start: end]) = minKPalindrome(prefix of s) + minKPalindrome(suffix of s)
代替检查字符串s
的每个前缀,我们只可以检查回文前缀。
if start[start:i] is palindrome {
minKPalindrome(s[start: end]) = 1 + minKPalindrome(s[i+1:end])
}
基本情况:
- if start > end, return 0
递归算法:
memo[start] = contains answer for s[start:end]
end = lenght(s) - 1
minKPalindrome(start, end) {
if start > end {
return 0
}
if ans is already saved in memo[start] {
return memo[start]
}
memo[start] = end - start + 1 // set maximum possible answer
for i = start to end {
if s[start:i] is palindrome {
memo[start] = min( memo[start], 1 + minKPalindrome(i+1, end))
}
}
return memo[start]
}
迭代算法:
对于迭代算法,我们将为字符串s
的前缀保存答案。
memo[i] = contains answer for s[0:i]
for i = 0 to length(s)-1 {
for j= 0 to i {
if s[j:i] is palindrome {
memo[i] = min( memo[i], 1 + memo[j-1])
}
}
}