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
}