【ACWing】824. 取现金

题目地址:

https://www.acwing.com/problem/content/description/826/

艾伦是一个非常富有的人,他在银行存有 n n n元钱,现在由于某些私人原因,他要将钱全部取出用于急用。已知银行的钞票共分 1 , 5 , 10 , 20 , 100 1,5,10,20,100 1,5,10,20,100 5 5 5种面值。出于携带方便的考虑,艾伦希望组成这 n n n元钱的钞票张数尽可能少。请问在给定 n n n的情况下,组成 n n n元钱的钞票张数最少是多少。

输入格式:
共一行,只包含一个整数 n n n

输出格式:
共一行,只包含一个整数,表示最少的钞票张数。

数据范围:
1 ≤ n ≤ 1 0 9 1≤n≤10^9 1n109

思路是贪心,从小到大遍历这些面值,对于每个面值,只有在“不得不用”的时候,才用该面值。例如,对于 1 1 1,显然如果不用 1 1 1,其余面值只能表示出 5 5 5的倍数,所以 n m o d    5 n\mod 5 nmod5就是 1 1 1的个数。对于其余面值的个数以此类推。证明不难,只需注意,对于任意方案,考虑 1 1 1这个面值,如果该面值的个数 x x x大于了 n m o d    5 n\mod 5 nmod5,那么一定有 x ≥ 5 x\ge 5 x5(因为如果 x < 5 x<5 x<5,那么 x = n m o d    5 x= n\mod 5 x=nmod5,就矛盾了),这样可以将 5 5 5 1 1 1替换为 1 1 1 5 5 5,总钞票数量变少了,矛盾。其余以此类推。代码如下:

#include <iostream>
using namespace std;

int n;
int a[] = {
    
    1, 5, 10, 20, 100};

int main() {
    
    
    scanf("%d", &n);

    int res = 0;
    for (int i = 0; i <= 3; i++) {
    
    
        res += n % a[i + 1] / a[i];
        n -= n % a[i + 1];
    }

    res += n / 100;
    printf("%d\n", res);
    return 0;
}

时空复杂度 O ( 1 ) O(1) O(1)

猜你喜欢

转载自blog.csdn.net/qq_46105170/article/details/121748021