You are given an integer array coins representing coins of different denominations and an integer amount representing a total amount of money.
Return the number of combinations that make up that amount. If that amount of money cannot be made up by any combination of the coins, return 0.
You may assume that you have an infinite number of each kind of coin.
The answer is guaranteed to fit into a signed 32-bit integer.
Example 1:
Input: amount = 5, coins = [1,2,5] Output: 4 Explanation: there are four ways to make up the amount: 5=5 5=2+2+1 5=2+1+1+1 5=1+1+1+1+1
Example 2:
Input: amount = 3, coins = [2] Output: 0 Explanation: the amount of 3 cannot be made up just with coins of 2.
Example 3:
Input: amount = 10, coins = [10] Output: 1
Constraints:
1 <= coins.length <= 3001 <= coins[i] <= 5000- All the values of
coinsare unique. 0 <= amount <= 5000
- the answer is guaranteed to fit into signed 32-bit integer
A:
首先 backtracking. 回溯。
Mistakes:
C++ 中,每个变量都需要显式初始化。类似于上面的,不然就是会random value
上面的LTE了。 加上memorization. (但是这个就比较麻烦。 所以还是用bottom-up 方式
经典的DP问题。 每次新增一个coin的值。 并对这个coin,用多个情况
class Solution { public: int change(int amount, vector<int>& coins) { vector<int> preCoins(1+amount,0); preCoins[0] = 1; // each time, add a new denomination . and then split with how many this new coid used for(int i =0;i< coins.size();i++){ int coin = coins[i]; vector<int> includeNewCoin = preCoins; // initially without new-coin case for(int k = 1; k* coin <= amount; k++){ for(int total = k * coin; total <=amount;total++){ includeNewCoin[total] += preCoins[total-k*coin]; } } preCoins = includeNewCoin; } return preCoins[amount]; } };
Errors:
一开始没考虑amount == 0, return should be 1.
改进:
我们采用的方法是一个硬币一个硬币的增加,每增加一个硬币,都从1遍历到 amount,对于遍历到的当前钱数j,组成方法就是不加上当前硬币的拼法 dp[i-1][j],还要加上,去掉当前硬币值的钱数的组成方法,当然钱数j要大于当前硬币值,状态转移方程也在上面的分析中得到了:
dp[i][j] = dp[i - 1][j] + (j >= coins[i - 1] ? dp[i][j - coins[i - 1]] : 0)
class Solution { public: int change(int amount, vector<int>& coins) { vector<int> V(1+amount,0); V[0] = 1; for(auto coin : coins){ for(int i = coin; i<= amount;i++ ) V[i] += V[i-coin]; //V[i] is for previous, without coin for i. V[i-coin] is use current coid for i } return V[amount]; } };
NOTE:
might cause overflow, thus need :
No comments:
Post a Comment