一、问题描述
有1元、5元、10元、50元、100元、500元的硬币各C1、C5、C10、C50、C100、C500枚。现要用这些硬币来支付A元,最少需要多少枚硬币?假设本题最少存在一种支付方案。(0 ≤ C1、C5、C10、C50、C100、C500 ≤ 109,0 ≤ A ≤ 109 )
二、问题分析
之前有一道类似的硬币问题,n种硬币支付S元,但每种硬币无限,求硬币数最多和最小是多少,可转化为DAG上的最长和最短路。但这道题每种硬币数量有限不好建图,且数据规模很大,必须用一种高效的算法。
如果我们每次选面值尽可能大的,就能保证硬币数越小,(可用反证法证明正确性)。
三、代码实现
1 #include<stdio.h> 2 #include<iostream> 3 #include<algorithm> 4 using namespace std; 5 6 const int V[6] = { 1,5,10,50,100,500 }; 7 int A,C[6]; 8 9 void slove() 10 { 11 int ans = 0; 12 for (int i = 5; i >= 0; i--) 13 { 14 int t = min(A / V[i], C[i]); 15 A -= t * V[i]; 16 ans += t; 17 } 18 19 printf("%d ", ans); 20 } 21 22 int main() 23 { 24 for (int i = 0; i < 6; i++) 25 scanf("%d", &C[i]); 26 scanf("%d", &A); 27 28 slove(); 29 30 return 0; 31 }
四、总结
这是最简单的贪心题吧!也提醒我们当数据规模很大时,要考虑到贪心算法,因为它非常高效。