目录
- 第二题(Leetcode原题)
- 题目描述
- 输入描述
- 输出描述
- 分析
第二题(Leetcode原题)
题目描述
给定不同面额的硬币(coins)和一个总金额(amount) 。写一个函数来计算可以凑成总金额所需的最少的硬币个数,如果没有任何一种硬币组合能满足,返回-1。
输入描述
输出描述
若存在可以凑成总金额所需的最少的硬币个数,则输出该数;否则输出为-1。
分析
- 一开始想的是用贪心算法,但后来发现不可以,比如输入总金额为20、硬币面额为1、5、6时,若采用贪心算法:20=6*3+1*2,一共需要5枚硬币,而实际只需4枚硬币即可,即20=5*4。
- 标准解法是动态规划算法:
- 定义dp[i]为总金额为i时所需要的最少硬币数,dp[0]=0;
- 状态转移方程:dp[i] = min(dp[i], dp[i-coin[j]] + 1)。+1是代表使用coin[j]一次。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
| int getMinCoins(int n, const vector<int>& coin) { vector<int> dp(n + 1, n + 1); dp[0] = 0; for (int i = 0; i <= n; ++i) { for (int j = 0; j < coin.size(); ++j) { if (coin[j] <= i) dp[i] = dp[i] < dp[i-coin[j]] + 1 ? dp[i] : dp[i-coin[j]] + 1; } } return dp[n] > n ? -1 : dp[n]; }
int main() { int n; cin >> n; vector<int> coin; while (cin.get() != '\n') { int value; cin >> value; coin.push_back(value); } cout << getMinCoins(n, coin) << endl; }
|