思路:完全背包。
首先分析问题我们可以知道,这个题的本质就是对于每一个硬币选于不选的问题,也就是所谓的背包问题。而后,这里的每一个硬币都是无限多的,也就是说,这不是01背包或者其他背包问题,而是对于完全背包的索引。
好了,那么知道了算法之后我们再看题目要求,说的是让选的硬币数恰好是amount,也就是说不存在装不满的状态,也不存在装不下的状态(这个是最基础的)。那么就需要我们为数组进行初始化,既然说是最少的数量,那么我们就把值赋值成比较大的数,这里直接用amount+1了,大小也是开在amount+1,开的大反而会错,因为会有别的状态混进来;开小了只会超出空间限制。
之后就是对于完全背包的模板套就行了,只不过max改成了min,每个硬币的价值都是1,所以需要+1。这是因为每个硬币都代表一个数量,也就是1,所以把硬币的值当作容量,把硬币本身这个数量当作价值。
注意:不要忘记为f[0]=0,这是因为要想达到答案,f[0]=0肯定会被转移到,这个时候才是正好amount个数值。其他的值不用变,直接赋值大一点就好。
class Solution {
public:int coinChange(vector<int>& coins, int amount) {vector<int>f(amount+1,amount+1);//数组不能开大,也不能开小,否则会有不同的状态混里面f[0]=0;//这里就是给初始化的值一个交代for(int i=0;i<coins.size();i++){for(int j=coins[i];j<=amount;j++){if(f[j-coins[i]]<amount+1)//也就是说在当前的状态里面就开始转移更新f[j]=min(f[j],f[j-coins[i]]+1);}}return f[amount]>=amount+1?-1:f[amount];//判断这个状态到底有没有更新,如果它的值还是初始值,那么就是没有解}
};