123最优硬币组合问题 | 豆包MarsCode AI刷题

136 阅读2分钟

一、题目解析:最优硬币组合问题

题目描述

小C有多种不同面值的硬币,每种硬币的数量是无限的。他希望知道,如何使用最少数量的硬币,凑出给定的总金额N。小C对硬币的组合方式很感兴趣,但他更希望在满足总金额的同时,使用的硬币数量尽可能少。

例如:小C有三种硬币,面值分别为 125。他需要凑出总金额为 18。一种最优的方案是使用三个 5 面值的硬币,一个 2 面值的硬币和一个 1 面值的硬币,总共五个硬币。

1、题目解析

这道题要求找出使用硬币最少的方式。我们则需要从大往小逐渐判断各个面值的硬币最多能够用几个并存起来然后输出。因此我们需要先对硬币的面值进行一次排序,然后再计算每个面值硬币可以用几个。

2、算法分析

我们需要对硬币的面额进行排序(降序),准备一个vector类型vec来保存每次使用的硬币的数值,然后进行循环,如果当前金额total>=此时的硬币金额(硬币面值先使用大的),则total减去当前硬币面值。往vec里面尾插当前硬币面值 如果total<当前硬币面额则使用下一个硬币金额再次进行比较,重复上面的步骤。 total=0时,得到使用硬币数量最少的方案。

代码实现

vector<int> solution(vector<int> array, int total) {
    sort(array.begin(),array.end(),greater<int>());
    int i=0;
    vector<int>vec;
    while(total>0)
    {
        if(total>=array[i])
        {
            vec.push_back(array[i]);
            total-=array[i];
        }
        else if(total<array[i])
        {
            i++;
        }
    }
    return vec;
}

代码分析

首先对存放硬币金额的vector类型array进行降序排序,使用i来记录当前可使用最大金额的下标(初始为0)。 使用一个vector类型vec来存放每一次使用的硬币的面额。 用while循环,当total>0时不断进行以下操作: 如果当前金额total>=当前可以用最大金额array[i],则向vec里面插入每次使用的硬币面额,total-=array[i]。如果total<array[i],则使用下一个硬币面额继续判断(i++)。 当total=0,则得到硬币使用数量最少的方案vec。

二、知识总结

sort()是快速排序的函数,sort()函数位于头文件algorithm里面 sort()第一个参数为array.begin()(是一种迭代器,返回的是array第一个元素的引用) sort()第二个参数为array.end()(是一种迭代器,返回的是array最后一个元素的引用) sort()第三个参数为greater()(是一个比较函数,用来告诉编译器使用降序排序) push_back()用于向vector类型里面尾插数据。