# 两个常规动态规划算法题，两个邪门的解

## LeetCode 322 零钱兑换

``````class Solution(object):
def coinChange(self, coins, amount):
def dfs(idx, target, cnt):
if idx == len(coins):
return
if (target + coins[idx] - 1) / coins[idx] + cnt >= self.ans:
return
if target % coins[idx] == 0:
self.ans = min(self.ans, cnt + target / coins[idx])
return
for j in range(target / coins[idx], -1, -1):
dfs(idx + 1, target - coins[idx] * j, cnt + j)

self.ans = float('inf')
coins = list(set(coins))
coins.sort(reverse=True)
dfs(0, amount, 0)
return -1 if self.ans == float('inf') else self.ans``````

## LeetCode 72 编辑距离

horse -> rorse (将 'h' 替换为 'r')
rorse -> rose (删除 'r')
rose -> ros (删除 'e')

intention -> inention (删除 't')
inention -> enention (将 'i' 替换为 'e')
enention -> exention (将 'n' 替换为 'x')
exention -> exection (将 'n' 替换为 'c')
exection -> execution (插入 'u')

``````class Solution:
def minDistance(self, word1, word2):
if not word1 or not word2:
return max(len(word1),len(word2))
stack1=[(0,0,0)]
stack2=[(len(word1),len(word2),0)]
mem1={}
mem2={}
while True:
newstack1=[]
while stack1:
i,j,lv=stack1.pop()
if (i,j) in mem2:
return lv+mem2[(i,j)]
if (i,j) in mem1:
continue
else:
mem1[(i,j)]=lv
if i<len(word1) and j<len(word2):
if word1[i]==word2[j]:
stack1.append((i+1,j+1,lv))
continue
else:
#rep
newstack1.append((i+1,j+1,lv+1))
if j<len(word2):
newstack1.append((i,j+1,lv+1))
#del
if i<len(word1):
newstack1.append((i+1,j,lv+1))
stack1=newstack1

newstack2=[]
while stack2:
i,j,lv=stack2.pop()
if (i,j) in mem1:
return lv+mem1[(i,j)]
if (i,j) in mem2:
continue
else:
mem2[(i,j)]=lv
if i>0 and j>0:
if word1[i-1]==word2[j-1]:
stack2.append((i-1,j-1,lv))
continue
else:
#rep
newstack2.append((i-1,j-1,lv+1))