class Solution {
public:
int minMoney(vector<int>& arr, int aim) { //数组中的值,可重复拿出来凑成aim,要求数最少
if(aim == 0){ //凑0,可以,但需要0张
return 0;
}
if(arr.empty()){ //当没有钱时,找不了
return -1;
}
//动态规划:用从最小的开始,进行凑,继承最少的张数
sort(arr.begin(), arr.end());
if(aim < arr.front())return -1; //aim比最小的面值小则返回0;
unordered_map<int, int> mp; //键存放的是金额,值存放张数
mp[0] = 0; //初始化
for(int i=1; i<=aim; i++){
for(int num: arr){
if(num <= i && mp.find(i-num) != mp.end()){ //可以凑, 找到了组合
if(mp.find(i) == mp.end()){ //如果还没创建
mp[i] = 1 + mp[i-num];
}else{ //已经有,取最大值
mp[i] = min( mp[i], 1+mp[i-num] );
}
}
}
}
return mp.find(aim) == mp.end() ? -1:mp[aim];
}
};