贪婪算法之兑换硬币及问题所在

问题:

以人民币的硬币为例,假设硬币数量足够多。要求将一定数额的钱兑换成硬币。要求兑换硬币数量最少。

思路说明:

这是用贪婪算法的典型应用。在本例中用python来实现,主要思想是将货币金额除以某硬币单位,然后去整数,即为该硬币的个数;余数则做为向下循环计算的货币金额。

这个算法的问题在于,得出来的结果不一定是最有结果。比如,硬币单位是[1,4,6],如果将8兑换成硬币,按照硬币数量最少原则,应该兑换成为两个4(单位)的硬币,但是,按照本算法,得到的结果是一个6单位和两个1单位的硬币。这也是本算法的局限所在。所谓贪婪算法,本质就是只要找出一个结果,不考虑以后会怎么样。

解决(Python)

#!/usr/bin/env python
#coding:utf-8

def change_coin(money):
    coin = [1,2,5,10,20,50,100]     #1分,2分,5分,1角,2角,5角,1元
    coin.sort(reverse=True)
    money = money*100               #以分为单位进行计算
    change = {}

    for one in coin:
        num_coin = money//one       #除法,取整,得到该单位硬币的个数
        if num_coin>0:
            change[one]=num_coin
        num_remain = money%one      #取余数,得到剩下的钱数
        if num_remain==0:
            break
        else:
            money = num_remain
    return change 

if __name__=="__main__":
    money = 3.42
    num_coin = change_coin(money)
    result = [(key,num_coin[key]) for key in sorted(num_coin.keys())]
    print "You have %s RMB"%money
    print "I had to change you:"
    print "    Coin    Number"
    for i in result:
        if i[0]==100:
            print "Yuan    %d    %d"%(i[0]/100,i[1])
        elif i[0]<10:
            print "Fen    %d    %d"%(i[0],i[1])
        else:
            print "Jiao    %d    %d"%(i[0]/10,i[1])

#执行结果
#You have 3.42 RMB
#I had to change you:
#    Coin    Number
#    Fen    2    1
#    Jiao    2    2
#    Yuan    1    3

贪婪算法之兑换硬币及问题所在

时间: 2024-10-18 17:35:07

贪婪算法之兑换硬币及问题所在的相关文章

利用动态方法修正贪婪算法中找硬币的问题

在博文:http://blog.csdn.net/qiwsir/article/details/31375449 中,讲述了如何用贪婪算法解决找硬币的问题,同时也指出了该方法存在的问题. 如何解决? 下面就是一个解决方案,在这里采用的是动态算法. def coinChange(centsNeeded, coinValues): minCoins = [[0 for j in range(centsNeeded + 1)] for i in range(len(coinValues))] minC

【入门OJ】1038:兑换硬币

题意很简单,最开始还在想是否要用完全背包方案数的方法,但是一看见是一元钱QAQ! 直接暴力,不用说,大水题! #include<iostream> #include<cstdio> #include<cstring> using namespace std; int cnt; int main() { for(int i=5;i<=100;i+=5) for(int j=2;j<=100;j+=2) for(int k=1;k<=100;k++) if

C语言值基本算法43—总结

C程序的基本算法共涵盖42个例题,包含了枚举.排列.逻辑判断.迭代.递推.字符串操作.矩阵操作.格式输出等内容. 相关的实现方法有的显得很笨拙,但足够说明问题,而且每个程序都经过作者亲测,保证可以运行.之所以称之为基本算法,就是为了测试基础知识的掌握,都是从原始的角度进行处理,没有运用过于花哨的处理技巧,作者也是在学习中进步,也希望这些代码对于没有基础或者基础薄弱的朋友带来帮助. 至此,基本知识就掌握了,我们常常会听说C的强大,因为它是面向过程的,在数学领域具有极好的应用,有必要进行进一步的学习

java 循环结构(二)关于for语句的运用,以下例子让你充分理解for循环

输出 import java.util.Scanner; public class text10{ public static void main(String[] args){ Scanner sc=new Scanner(System.in); int i,j,n; n=sc.nextInt(); for(i=1;i<=n;i++) { for(j=1;j<=n;j++) { System.out.print(i); } System.out.println(); } } } 输出金字塔※

算法设计与分析 - 李春葆 - 第二版 - pdf-&gt;word v3

1 1.1 第1章─概论 2 3 1.1.1 练习题 4 1. 下列关于算法的说法中正确的有( ). 5 Ⅰ.求解某一类问题的算法是唯一的 6 Ⅱ.算法必须在有限步操作之后停止 7 Ⅲ.算法的每一步操作必须是明确的,不能有歧义或含义模糊 8 Ⅳ.算法执行后一定产生确定的结果 9 A. 1个 B.2个 C.3个 D.4个 10 2. T(n)表示当输入规模为n时的算法效率,以下算法效率最优的是( ). 11 A.T(n)= T(n-1)+1,T(1)=1 B.T(n)= 2n2 12 C.T(n)

C++实现最少硬币兑换问题

最少硬币兑换问题 #include<iostream> #include<fstream> using namespace std; int n,L; //n种硬币L长的数组 int c[13][20]; int T[13];//硬币面值 int jisuan(int i,int j); int main() { fstream file("2.1_input.txt"); //这是需要读取数据的文件的路径. fstream file2("2.1_ou

Ex 6_18 硬币有限的兑换问题_第七次作业

子问题定义: 定义一个二维数组b,其中b[i][j]表示前i个币种是否能兑换价格j,表示第i个币种的面值,第i个币种的使用有两种情况,若使用,则b[i][j]=b[i-1][j-],若不使用,则b[i][j]=b[i-1][j] 递归关系: 初值设定: 求解顺序: 按下标从小到大依次求解数组b每一行的值,最后二维数组b的右下角元素值即为最终的解. 1 package org.xiu68.ch06.ex7; 2 3 public class Ex6_18 { 4 5 //面值为x1,x2,x3,.

Ex 6_17 数量无限的硬币兑换问题_第七次作业

子问题定义:定义一个数组b,大小比兑换价格的大小多一个元素,其中b[i]表示是否能用面值为x1,x2,x3,..,xn的硬币兑换价格i. 递归关系: 初值设定:设b[0]=true 求解顺序:按下标从小到大依次求解b[i]的值,最后返回b[v]中的结果即为最终结果. 1 package org.xiu68.ch06.ex7; 2 3 public class Ex6_17 { 4 5 //数量无限的面值为x1,x2,x3,...,xn的硬币是否能兑换价格v 6 public static voi

HDU 1284 钱币兑换问题 (完全背包)

钱币兑换问题 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total Submission(s): 7658    Accepted Submission(s): 4547 Problem Description 在一个国家仅有1分,2分,3分硬币,将钱N兑换成硬币有很多种兑法.请你编程序计算出共有多少种兑法. Input 每行只有一个正整数N,N小于32768. Outpu