var isVisit map[string]int// 保留已经得到的结果,该结构相当于一个备忘录// 记忆化搜索函数调用者funcminDistance(word1 string, word2 string)int{/* 1. 进行一些预处理 */
isVisit =make(map[string]int)/* 2. 开始调用记忆化搜索函数,返回记忆化搜索结果 */returnminDistanceExec(word1, word2)}// 记忆化搜索函数funcminDistanceExec(word1 string, word2 string)int{/* 3. 判断是否需要返回结果以及进行一些剪枝 (特殊情况处理) */iflen(word1)==0{returnlen(word2)}iflen(word2)==0{returnlen(word1)}// 如果该问题已经求解过了,那么直接返回结果
hashVal :=hash(word1, word2)if x, ok := isVisit[hashVal]; ok {return x
}/* 4. 如果没求解,则继续调用记忆化搜索函数,得出结果 (一般情况处理) */
ans :=0if word1[len(word1)-1]== word2[len(word2)-1]{
ans =minDistanceExec(word1[:len(word1)-1], word2[:len(word2)-1])}else{
a :=minDistanceExec(word1[:len(word1)-1], word2)
b :=minDistanceExec(word1, word2[:len(word2)-1])
ans =min(a, b)+1}// 记录该问题的结果,加入备忘录
isVisit[hashVal]= ans
return ans
}// 由于备忘录的键值是 1 个字符串,而记忆化搜索函数需要 2 个字符串参数才能唯一标识一个子问题,// 所以,这里采用哈希的方式,把两个参数进行哈希,生成一个键值来唯一的标识这个参数组合,// 即: 用「1个字符串」 唯一标识 「1个子问题」。funchash(a, b string)string{return a +"|"+ b
}funcmin(a, b int)int{if a > b {return b
}return a
}
var hasResult map[string]bool// 保留已经得到的结果,该结构相当于一个备忘录// 记忆化搜索函数调用者funcisMatch(s string, p string)bool{/* 1. 进行一些预处理 */
hasResult =make(map[string]bool)/* 2. 开始调用记忆化搜索函数,返回记忆化搜索结果 */returnisMatchExec(s, p)}// 记忆化搜索函数funcisMatchExec(s string, p string)bool{/* 3. 判断是否需要返回结果以及进行一些剪枝 (特殊情况处理) */if s == p {returntrue}if p ==""{return s ==""}
ends, endp :=len(s)-1,len(p)-1if s ==""{if p[endp]=='*'{returnisMatchExec(s, p[:endp-1])}returnfalse}// 如果该问题已经求解过了,那么直接返回结果
key :=hash(s, p)if x, ok := hasResult[key]; ok {return x
}/* 4. 如果没求解,则继续调用记忆化搜索函数,得出结果 (一般情况处理) */
ans :=falseif s[ends]== p[endp]|| p[endp]=='.'{
ans =isMatchExec(s[:ends], p[:endp])}else{if p[endp]=='*'{if p[endp-1]== s[ends]|| p[endp-1]=='.'{
ans =isMatchExec(s, p[:endp])||isMatchExec(s[:ends], p)||isMatchExec(s, p[:endp-1])}else{
ans =isMatchExec(s, p[:endp-1])}}}// 记录该问题的结果,加入备忘录
hasResult[key]= ans
return ans
}// 由于备忘录的键值是 1 个字符串,而记忆化搜索函数需要 2 个字符串参数才能唯一标识一个子问题,// 所以,这里采用哈希的方式,把两个参数进行哈希,生成一个键值来唯一的标识这个参数组合,// 即: 用「1个字符串」 唯一标识 「1个子问题」。funchash(s, p string)string{return s +"|"+ p
}
var isVisit map[string]int// 保留已经得到的结果,该结构相当于一个备忘录// 记忆化搜索函数调用者funcminDistance(word1 string, word2 string)int{/* 1. 进行一些预处理 */
isVisit =make(map[string]int)/* 2. 开始调用记忆化搜索函数,返回记忆化搜索结果 */returnminDistanceExec(word1, word2)}// 记忆化搜索函数funcminDistanceExec(word1 string, word2 string)int{/* 3. 判断是否需要返回结果以及进行一些剪枝 (特殊情况处理) */iflen(word1)==0{returnlen(word2)}iflen(word2)==0{returnlen(word1)}// 如果该问题已经求解过了,那么直接返回结果
hashVal :=hash(word1, word2)if x, ok := isVisit[hashVal]; ok {return x
}/* 4. 如果没求解,则继续调用记忆化搜索函数,得出结果 (一般情况处理) */
ans :=0if word1[len(word1)-1]== word2[len(word2)-1]{
ans =minDistanceExec(word1[:len(word1)-1], word2[:len(word2)-1])}else{
a :=minDistanceExec(word1[:len(word1)-1], word2)
b :=minDistanceExec(word1[:len(word1)-1], word2[:len(word2)-1])
c :=minDistanceExec(word1, word2[:len(word2)-1])
ans =min(a, b, c)+1}// 记录该问题的结果,加入备忘录
isVisit[hashVal]= ans
return ans
}// 由于备忘录的键值是 1 个字符串,而记忆化搜索函数需要 2 个字符串参数才能唯一标识一个子问题,// 所以,这里采用哈希的方式,把两个参数进行哈希,生成一个键值来唯一的标识这个参数组合,// 即: 用「1个字符串」 唯一标识 「1个子问题」。funchash(a, b string)string{return a +"|"+ b
}// 这里我重写了min函数,让它可以计算n个参数的最小值funcmin(arr ...int)int{iflen(arr)==1{return arr[0]}
a, b := arr[0],min(arr[1:]...)if a > b {return b
}return a
}
var inf int// 无穷大var amount map[int]int// 保留已经得到的结果,该结构相当于一个备忘录// 记忆化搜索函数调用者funcgetMoneyAmount(n int)int{/* 1. 进行一些预处理 */
amount =make(map[int]int)
inf =100000000000/* 2. 开始调用记忆化搜索函数,返回记忆化搜索结果 */returngetMoneyAmountExec(1, n)}// 记忆化搜索函数funcgetMoneyAmountExec(l, r int)int{/* 3. 判断是否需要返回结果以及进行一些剪枝 (特殊情况处理) */if l >= r {return0}// 如果该问题已经求解过了,那么直接返回结果
hashNumber :=hash(l,r)if x, ok := amount[hashNumber]; ok {return x
}/* 4. 如果没求解,则继续调用记忆化搜索函数,得出结果 (一般情况处理) */
ans := inf
for i := l; i <= r; i++{
left :=getMoneyAmountExec(l, i-1)
right :=getMoneyAmountExec(i+1, r)
ans =min(ans,max(left, right)+i)}// 记录该问题的结果,加入备忘录
amount[hashNumber]= ans
return ans
}// 由于备忘录的键值是 1 个整数,而记忆化搜索函数需要 2 个整数参数才能唯一标识一个子问题,// 所以,这里采用哈希的方式,把两个参数进行哈希,生成一个键值来唯一的标识这个参数组合,// 即: 用「1个整数」 唯一标识 「1个子问题」。funchash(l,r int)int{
off :=10return(r << off)| l
}funcmin(a, b int)int{if a > b {return b
}return a
}funcmax(a, b int)int{if a > b {return a
}return b
}