有一個貨幣系統,有n 種硬幣,每種硬幣的面值為 v1,v2,……,vn, 且 v1 必定為 1 , 目的是兌換價值為 sum 的錢,讓硬幣數量最少。
result[ j ] 表示價值總錢為 j 的最少硬幣數,
print[ j ] 表示價值錢數為 j 時用的是哪個硬幣來換的。
當只有 1 種 硬幣時, 即只有面值為 1 的硬幣,那有多少錢,兌換後的數量肯定就是多少。所以 result[ j ] = j, j = 0,…,sum
當考慮第 i (2,……,n ) 種硬幣時, 如果當前的價值錢數大於這種硬幣的面值,且用這種硬幣兌換後的硬幣總數量要比不用這種硬幣兌換少的話,就兌換,否則不兌換,
遞推公式為:
result[ j ] = max{ result[ j ], result[ j-v[i]+1 ] }; result[ j ] 大說明不兌換的硬幣少,否則兌換後的硬幣少。
代碼如下
#include <iostream>#include <vector>#include <map>using namespace std;int main(int argc, char** argv) {int num,sum;vector<int> v;cout<<"輸入總錢數"<<endl;cin>>sum;cout<<"輸入硬幣種類數"<<endl;cin>>num;cout<<"分別輸入每種硬幣的面值"<<endl;int i=0,j=0,temp;for(i=0;i<num;++i){cin>>temp;v.push_back(temp);}vector<int> result;for(i=0;i<=sum;++i)result.push_back(i);vector<int> print(sum+1,0); //輸出每種硬幣的個數 for(i=1;i<num;++i){for(j=v[i];j<=sum;++j){temp = result[j-v[i]]+1;if(temp < result[j]){result[j] = temp;print[j] = i;}}}cout<<"最少硬幣數為 "<<result[sum];map<int,size_t> map1;j = sum;while(j>0){map1[print[j]]++;j -= v[print[j]];}for(i=0;i<num;++i)cout<<endl<<"面值為 "<<v[i]<<" 的硬幣數量為 "<<map1[i];return 0;}
運行結果