动态规划硬币找零问题
题目描述:给予不同面值的硬币若干种种(每种硬币个数无限多),如何用若干种硬币组合为某种面额的钱,使硬币的的个数最少?
在现实生活中,我们往往使用的是贪心算法,比如找零时需要13元,我们先找10元,再找2元,再找1元。如果我们的零钱可用的有1、2、5、9、10。我们找零18元时,贪心算法的策略是:10+5+2+1,四种,但是明明可以用两个9元的啊。这种问题一般使用动态规划来解决。
1 #include<iostream> 2 #include<vector> 3 using namespace std; 4 void findMin(int money, vector<int> &coin){ 5 vector<int> dp(money+1, 0); 6 vector<int> coinVal(money+1, 0); 7 for(int i=1; i<=money; ++i){ 8 int minNum=i; 9 int curMoney=0; 10 for(int j=0; j<coin.size(); ++j){ 11 if(i>=coin[j] && dp[i-coin[j]]+1<=minNum){ 12 //如果能找开就更新 13 if(i-coin[j]==0 || coinVal[i-coin[j]]!=0){ 14 minNum=dp[i-coin[j]]+1; 15 curMoney=coin[j]; 16 } 17 } 18 } 19 dp[i]=minNum; 20 coinVal[i]=curMoney; 21 } 22 if(coinVal[money]==0){ 23 cout<<"找不开"<<endl; 24 }else{ 25 cout<<dp[money]<<endl; 26 while(money){ 27 cout<<coinVal[money]<<" "; 28 money=money-coinVal[money]; 29 } 30 } 31 } 32 int main(){ 33 int money=18; 34 vector<int> coin={5,10}; 35 findMin(money, coin); 36 return 0; 37 }