# Knapsack problem
###### tags: `Steven` `DP`
# 0/1
# 有限
# 無限
## [322. Coin Change](https://leetcode.com/problems/coin-change/)
### top-down
#### TLE
```c++
class Solution {
public:
int coinChange(vector<int>& coins, int amount) {
if(amount == 0) {
return 0;
}
int mn = INT_MAX;
for(const auto &coin : coins) {
if(amount - coin >= 0) {
int ret = coinChange(coins, amount - coin);
if(ret == -1)
continue;
mn = min(mn, ret);
}
}
return mn == INT_MAX ? -1 : mn + 1;
}
};
```
#### With Memoization
```c++
#include <bits/stdc++.h>
using namespace std;
class Solution
{
private:
int cache[10001];
int go(vector<int> &coins, int amount)
{
if (amount == 0) {
return 0;
}
if (cache[amount] != 0x3f3f3f3f) {
return cache[amount];
}
int mn = INT_MAX;
for (const auto &coin : coins) {
if (amount - coin >= 0) {
int ret = go(coins, amount - coin);
if (ret == -1)
continue;
mn = min(mn, ret);
}
}
cache[amount] = mn == INT_MAX ? -1 : mn + 1;
return cache[amount];
}
public:
int coinChange(vector<int> &coins, int amount)
{
memset(cache, 0x3f, sizeof(cache));
return go(coins, amount);
}
};
```
##### My stupid bug ...
```c++
class Solution {
private:
int cache[10001];
int go(vector<int>& coins, int amount) {
if(amount == 0) {
return 0;
}
if(cache[amount] != 0) {
return cache[amount];
}
int mn = INT_MAX;
for(const auto &coin : coins) {
if(amount - coin >= 0) {
int ret = coinChange(coins, amount - coin); // bro... calling the wrong function lol
if(ret == -1)
continue;
mn = min(mn, ret);
}
}
cache[amount] = mn == INT_MAX ? -1 : mn + 1;
return cache[amount];
}
public:
int coinChange(vector<int>& coins, int amount) {
memset(cache, 0x3f, sizeof(cache)); // no wonder this memset thing will cause timeout lol
return go(coins, amount);
}
};
```
### bottom-up
```c++
class Solution {
public:
int coinChange(vector<int>& coins, int amount) {
// 無限背包
int dp[amount + 1];
memset(dp, 0x3f, sizeof(dp));
dp[0] = 1; // base condition
for(const auto &coin : coins) {
for(int i = 0; i + coin <= amount; i++) {
if(dp[i] > 0) {
dp[i + coin] = min(dp[i + coin], dp[i] + 1);
}
}
}
return dp[amount] == 0x3f3f3f3f ? -1 : dp[amount] - 1;
}
};
```