`
aladdin_leon
  • 浏览: 117522 次
  • 性别: Icon_minigender_1
  • 来自: 哈尔滨
社区版块
存档分类
最新评论

利用动态规划解决兑换问题

阅读更多

      问题是这样的:某个国家一共发行了a1,a2,a3,...,ak种不同面值的钞票,为了方便起见,假设a1,a2,a3,...ak依次增大。现在手上有的钱数为n,请问要如何把兑换成a1,a2,a3,...,ak这些钞票,使得所用的钞票的量为最少。这个问题看上去很简单,举一个例子,如果有1元,5元,10元3种钞票,而要兑换107元,于是就有a1=1,a2=5,a3=10,n=107。那么我们用面额最大的去除,那就是最大面额钞票的张数,比如说n/a3=107/10=10,亦即10元的10张;除过之后就有余数7,再用次大面额钞票去除,7/5=1,余数为2,所以5元钞票为1张;再把余数用第三大的面额去除,2/1=2,余数为0,于是一元的2张,没有剩下的钞票了,因此结果就是10元的7张,5元的1张,1元的2张。不过对有1元,5元,10元这个例子倒是正确,那么如果面额换为1元,3元,4元,要兑换10元的钞票呢?用上面的方法算一下,就是4元的2张,1元的2张,一共用了4张的钞票。但是若用2张3元的,1张4元的也能兑换出10元的,但却只用了3张钞票。所以看来平常的方法并不能解决“使所用钞票的量为最少”这个问题
     这个问题有很多的解法,这里只想介绍利用动态规划(Dynamic Programming)和回溯的技巧来解决。
     首先说说用到的数据结构,假设n是要兑换的钱数,k是能够提供的面额数目,如果要兑换100元,提供面额为1元,5元,7元的3种钞票于是有n=100,k=3。用一个数组base[]把面额先保存好,因此就有base[0]=1,base[1]=5,base[2]=7。但是这里我们假设一定提供面额为一元的钞票,否则可能有一些值兑换不出来。我们再用一个数组money[]存放兑换的钞票数,因此money[i]就是i元钱兑换出来的钞票数,由于money[0]表示0元兑换出来的钞票数,那么很自然就是0了,money[1]按照上面的假设一定是1。
     其次我们说说具体的算法,假设现在要兑换i元,先看i-base[0],i-base[1],... ,i-base[k-1]是什么。例如:i=10,而面额是{1,3,4},于是这几个值就是10-1=9,10-3=7,10-4=6,换句话说,如果已经兑换好了9元7元或6元的话,要兑换十元只不过是加一张钞票而已。因此,在i-base[j]的情况下,就是多一张j元。但是,如何知道兑换i-base [j]要多少张钞票呢?别忘了money[]啊,该钞票的张数就在money[i-base[j]]中。如果已经已经兑换出i-base[j]元,用了money[i-base[j]]张钞票,于是再多加一张base[j]元就可以兑换出i元了,这样兑换i元一共用了money[i-base[j]]+1张钞票。
      但是我们还没有解决题目所要求的钞票张数最少的问题,所以我们就要求出各个money[i-base[j]]+1的极小值来(j=1,2,...,k),再存在money[i]中,于是money[i]就是兑换i元的最少钞票张数了。要注意:因为i-base[j]一定小于i,所以在计算money[i]时,在i之前的值就一定要先算出来,这样money[i-base[j]]才会一个有意义的值。
      说了很多,下面看看一个具体的规划的表格,还是以n=10,base[]={1,3,4}为例:

                                    i                 money[i]               i-base[j]
                              ------------------------------------------------------------
                                   0                     0                        --, --  , --
                                   1                     1                        --, --  , --
                                   2                     2                    2-1, 2-3*, 2-4*
                                   3                     1                    3-1, 3-3 , 2-4*
                                   4                     1                    4-1, 4-3 , 4-4
                                   5                     2                    5-1, 5-3 , 5-4
                                   6                     2                    6-1, 6-3 , 6-4  
                                   7                     2                    7-1, 7-3 , 7-4
                                   8                     2                    8-1, 8-3 , 8-4
                                   9                     3                    9-1, 9-3 , 9-4
                                 10                     3                  10-1,10-3 ,10-4                       
                             -------------------------------------------------------------
     *表示小于零,不用理会极小值,只要根据表格进行回溯就能得出结果了,看表格发现用10-3和10-4进行回溯的结果是一样的,也就是3+3+4=10和4+4+3=10的道理了,C语言的代码如下: 

  1. #include  <stdio.h></stdio.h>   
  2. #include  <stdlib.h></stdlib.h>   
  3. #define   MAXSIZE   100   
  4. #define   min(a,b)  ((a) <= (b) ? (a) : (b))   
  5.   
  6. int  main(void)  {   
  7.        int  money[MAXSIZE+1];   
  8.        int  base[] = { 1, 3, 4 };   
  9.        int  k = sizeof(base)/sizeof(int);   
  10.        int  n;   
  11.        int  i, j, MIN;   
  12.        char line[100];   
  13.        printf("\nMinimum Money Change Program");   
  14.        printf("\n----------------------------");   
  15.        printf("\n\nBase Values : ");   
  16.        for (i = 0; i < k; i++)   
  17.               printf("%d ", base[i]);   
  18.        printf("\n\nYour input please --> ");   
  19.        gets(line);   
  20.        n = atoi(line);   
  21.        money[0] = 0;             
  22.        money[1] = 1;       
  23.        for (i = 2; i <= n; i++)  {    
  24.                  MIN = n;              
  25.                  for (j = 0; j < k; j++)   
  26.                          if (i >= base[j])   
  27.                                   MIN = min(money[i-base[j]]+1, MIN);   
  28.                  money[i] = MIN;   
  29.        }   
  30.        printf("\n\nMinimum = %d", money[n]);   
  31.        getchar();   
  32. }     

     当然这个程序还有一个不足,那就是没有将每个面额的钞票的张数输出,还需要对程序进行一些改进,有兴趣一起研究一下吧...

分享到:
评论

相关推荐

    绿色出行低碳生活大数据解决方案

    低碳生活,绿建未来”云植树活动采取“线上线下”相结合的方式,参与者可以利用每天上下班途中、工作中、生活中的实地健步走数据,兑换对应数量的小树苗,“种植”在虚拟的地城市地图上,“云植树”绿化城市。...

    融东圈圈交互式广告平台APP

    7) 显示用户的金币数量,用户可对红包广告、动态信息进行评论及分享获得金币,获得金币后可在金币商城兑换礼品。 8)用户有两种购物方式,现金购物和金币购物; 特点 【低门槛】无需认证,坐在家里,1元钱就能把信息...

    后疫情时代商业综合体营销数字化解决方案.pptx

    会员体系优化:完善会员制度,提供积分兑换、优惠券、会员专享活动等福利,增加客户忠诚度。 跨界合作与创新:与其他产业、品牌进行跨界合作,推出创新产品与服务,拓宽市场份额。 线上线下融合营销:举办线上线下...

    药店数字化营销解决方案.doc

    社交媒体营销:利用社交媒体平台(如微信、微博、抖音等)进行药店的宣传和推广。通过发布健康资讯、药品知识、用户评价等内容,提高药店的知名度和美誉度,吸引更多潜在客户。 优惠活动与会员制度:开展各种优惠...

    华为编程开发规范与案例

    上面的问题解决起来很容易,只需在第一行代码中增加一个判断条件即可,如下:  for(i=0; i&lt;pSysHead-&gt;dbf_coun && i ; i++) // MAX_DB_NUM=127 这样就保证了循环变量i的值在正常范围内,从而避免了对指针pDBFat...

    本科毕设基于微信小程序的街舞交流平台小程序源码.rar

    3. 兑换板块:积分可以直接兑换现金。 4. 个人信息:个人界面包括头像,昵称,我的视频,我的活动,我的积分,退出。 本章主要从系统的总体架构、前后端框架设计出发,详细描述本系统的各个功能的设计思路和解决...

    ThinkSNS开源社交论坛系统 v4.6.1 bulid0630

    分类管理,热门热评类别等多种排序机制,呈现社区精选动态资讯,支持用户投稿,后台审核,使用最适应用户习惯的页面规划,助力运营者与使用者保持高度粘性,把握信息传播渠道。详细介绍...

    套利问题的贪心算法设计 (2007年)

    通过对套利问题的具体分析,利用该问题本身具有的一些特性,并结合实际的6种货币汇率的交叉兑换数据,提出了一个用贪心算法解决该问题的可行方案,同时给出了示例数据的求解结果;讨论了套利的实际可操作性。

    PHP云人才系统(PHPYun) 4.6 UTF-8.rar

    PHP云人才系统(PHPYun)是专为中文用户设计和开发,程序源代码100%完全开放的一个采用PHP和MySQL数据库构建的高效的人才与企业求职招、聘解决方案,在尊重版权的前提下能极大的满足站长对于网站程序进行二次开发。...

    基于一站式购物广场顾客积分管理优化系统的毕业设计实现.zip

    这个基于一站式购物广场顾客积分管理优化系统的毕业设计实现是一个全面的解决方案,旨在提高广场顾客的购物体验,增加他们的忠诚度,并提高广场的运营和管理水平。该系统将提供许多功能来实现这一目标,包括积分管理...

    最新小程序校园二手交易平台的小程序+ssm.zip

    该项目利用微信平台的易用性和普及性,结合SSM框架的高效数据处理能力,为用户提供了一个简便、可靠的校园内二手交易解决方案。 以下是该微信小程序校园二手交易平台的核心功能和特点: 1. **个人中心管理**:用户...

    DSA_questions

    该存储库包含我最近几个月解决的所有问题。 这里是问题清单: Q1。 唯一编号II Q2。 唯一编号III Q3。 ABCD模式 Q4。 激进的牛 Q5。 提取所有子数组 Q6。 二进制搜索 Q7。 图书分配 Q8。 气泡排序 Q9。 编码块...

    最新小程序停车共享小程序+ssm.zip

    微信小程序“停车共享小程序Ssm.zip”是一款为城市停车...这款小程序不仅提供了一个全面的停车共享管理平台,还通过智能化服务和数据支持,帮助解决城市停车难的问题,同时也为停车场运营商提供了增值服务和盈利模式。

    Veno-3.0.7-pre-release

    Veno Os让你在V4-V6互联互通,轻轻松松,利用它你可以实现...4、用户到期后仍然可以使用Veno,但带宽被限制为5KB/s,兑换积分后恢复正常 5、解决了360提示风险软件的bug 6、安装过程会提示安装驱动,请点击“继续安装”

    最新小程序电影院订票选座系统设计及实现+ssm.zip

    8. **用户反馈机制**:建立完善的用户反馈系统,及时解决用户在使用过程中遇到的问题。 整个系统以微信小程序为前端,便于用户随时随地访问和使用;后端采用SSM框架,确保了数据处理的效率和稳定性。这款小程序不仅...

    c语言经典案例

    实例120 递归解决分鱼问题 159 实例121 小数分离 160 实例122 求任意数的n次幂 161 实例123 固定格式输出当前时间 163 实例124 设计函数计算学生平均身高 164 实例125 求数组元素中的最小值 165 实例126 打印1~5的...

    最新小程序校园二手平台的设计与实现+ssm.zip

    该项目整合了微信生态和SSM(Spring, Spring MVC, MyBatis)框架的技术优势,利用微信平台的普及性和便捷性,结合SSM框架的高效数据处理能力,为用户提供了一个功能全面、操作简便的二手交易解决方案。 以下是该...

    电子商务网站设计原理.pdf

    21.Web 服务:是一种可以用来解决跨网络应用集 成问题的开发模式,这种模式为实现"软件作为服 务"提供了技术保障。 22.数据集成: 数据集成通过应用间的数据交换从而 达到集成,主要解决数据的分布性和异构性问题,...

    基于区块链的商城积分系统.pdf

    形成了商城、商家、会员等三者之间的联盟链,利用区块链技术的去中心化、共识信任、可靠时序分布式数据库、集体维护等技术特点,解决了商城积分系统开发成本高、积分零散、积分消费乏力、积分使用限制多、积分兑换繁琐...

    科汛(KesionCMS) 9.5.140102 UTF8.rar

    科汛(KesionCMS)产品由我司独立开发的一套万能建站产品,是CMS行业最流行的网站建设解决方案之一。软件制作权登记号为:2012SR058633。系统包括文章、图片、下载、问答、会员、论坛、微博、黄页、产品库、企业空间...

Global site tag (gtag.js) - Google Analytics