# Leetcode 322. Coin Change
## 題解
### 動態規劃
#### Top down
```python!
import math
class Solution:
def coinChange(self, coins: List[int], amount: int) -> int:
n = len(coins)
memo = [0 for i in range(amount)]
def bfs(rem: int):
if rem < 0: return -1
if rem == 0: return 0
if memo[rem-1] != 0: return memo[rem-1]
mini = (10 ** 4) + 1
for coin in coins:
res = bfs(rem - coin)
if res >= 0 and res < mini:
mini = res + 1
memo[rem-1] = -1 if mini == (10 ** 4) + 1 else mini
return memo[rem-1]
if amount == 0: return 0
bfs(amount)
return memo[amount-1]
```
#### Bottom up (不是最優)
```python!
class Solution:
def coinChange(self, coins: List[int], amount: int) -> int:
# Time complexity: O(n)
# Space complexity: O(n)
# Bottom up
# SOS:
# f(n) = min(f(n-ci)) + 1
# f(0) = 0
# n < 0 => f(n) = -1
if amount == 0: return 0 # edge case
int_max = (10 ** 4) + 1
memo = [0 for i in range(amount)]
def f(n: int):
if n < 0: return -1
if n == 0: return 0
if memo[n-1]: return memo[n-1]
mini = int_max
for coin in coins:
res = f(n-coin)
if res >= 0 and res < mini:
mini = res + 1
memo[n-1] = mini
return memo[n-1]
for i in range(1, amount+1):
f(i)
return -1 if memo[amount-1] == int_max else memo[amount-1]
```