• 硬币找零问题,动态规划基础,百度面试题


    问题描述:给出几种面值的硬币,要求用这几种硬币找零出所给零钱数,用的硬币数要最少

    过去我们用过贪心法解决此类问题,包括本人在百度面试时,也是用的贪心法(面试官对这个解答不满意),贪心法只适用于硬币特殊的情况下(1,3,5),如果现在硬币的面值为10,7,3,1,要求给出21的找零方案,那么贪心会给出10,7,3,1的方案,而不是3个7块的最佳方案。

    那么动态规划又该如何解决,动态规划在于在解决问题的途中用到之前的得到的答案。

    思考:求n的找零方案时,可将问题分解为1-(n-1)的找零方案中加上一个已知面值的硬币,求其最小值便可。

    代码如下:

    #include<iostream>
    using namespace std;
    
    //三个参数依次是硬币面值数组,硬币种类,给出的零钱
    void getMin(int *values,int valueKinds,int money){
        int *coinUsed = new int[money+1]();
        int *coinUsedNum = new int[money+1]();//(之前写的代码无法得出在无法找零情况下的正确答案,用这个数组不仅可以记录给出的硬币,还可以得出是否能找开的情况) 
        coinUsed[0] = 0;
        for(int cent=1;cent<=money;cent++){
            //每个零钱找零的最大值便是最小面值组成的个数 
            int minCent = cent;
            int moneyUsed = 0;
            for(int kind=0;kind<valueKinds;kind++){
                if(values[kind]<=cent){
                    //所查找找零最小数为已知的零钱找零数 + 一个已有面值,便是最少硬币方案 
                    int temp = coinUsed[cent - values[kind]] + 1;
                    //此处应该做一个判断,即是否找得开,找不开便不必更新最小值 
                    if(temp <= minCent && (cent == values[kind] || coinUsedNum[cent - values[kind]] != 0)){
                        minCent = temp;
                        moneyUsed = values[kind];
                    }
                }
            }
            coinUsed[cent] = minCent;
            coinUsedNum[cent] = moneyUsed;
        }
        if(coinUsedNum[money] == 0){
            printf("面值为%d的零钱找不开!", money);
        } else {
            printf("面值为%d的最少找零数为%d,", money,coinUsed[money]);
            printf("找零面值分别为:");
            while(money>0){
                printf(" %d",coinUsedNum[money]);
                money -= coinUsedNum[money];
            }
        }
    }
    
    int main(){
        int a[5] = {2,5,10,21,25};
        int money = 24;
        getMin(a,5,money);
    } 
  • 相关阅读:
    局部类
    内部类
    程序的异常
    四种修饰符
    接口之间的多继承
    多态
    继承父类并实现多个接口
    接口内容小结
    接口的静态方法和私有方法
    顺序栈与链式栈
  • 原文地址:https://www.cnblogs.com/tz346125264/p/7341143.html
Copyright © 2020-2023  润新知