经验首页 前端设计 程序设计 Java相关 移动开发 数据库/运维 软件/图像 大数据/云计算 其他经验
当前位置:技术经验 » 程序设计 » 编程经验 » 查看文章
动态规划-最少硬币问题
来源:cnblogs  作者:DNE  时间:2018/10/15 9:05:48  对本文有异议

问题描述:设有n种不同面值的硬币,各硬币的面值存在于数组T[1:n]中。现要用这些面值的硬币来找钱。可以使用的各种面值的硬币个数存于数组Coins[1:n]中。对任意钱数0≤m≤20001,设计一个最少硬币找钱m的方法。

算法设计:对于给定的1≤n≤10 ,硬币面值数组T和可以使用的各种面值的硬币数组Coins,以及钱数m, 0≤m≤20001,计算找钱m的最少硬币数。

数据输入:由文件input. Txt提供输入数据,文件的第1行中只有一个整数给出n的值,第2行起每行两个数,分别是T[j]和Coins[j]。最后一行是要找的钱数m。

结果输出:将计算出的最少硬币数输出到文件output.txt。问题无解时输出-1。

 

输入文件示例input.txt:

3

1 3

2 3

5 3

18

输出文件示例output.txt:

5

 

关注点:

1.多重背包 (每个物品有固定次数上限)

2.求的是最少

3.背包不能有空

 

代码:

  1. 1 #include<stdio.h>
  2. 2 #include<stdlib.h>
  3. 3 int maxint=2147483647;
  4. 4 void getit(int* t,int* coin,int ncoin,int money,int **m)
  5. 5 {
  6. 6 m[ncoin][0]=0;
  7. 7 for(int i=1;i<=money;i++)
  8. 8 {
  9. 9 m[ncoin][i]=maxint;
  10. 10 for(int j=1;j<=coin[ncoin];j++)
  11. 11 if(i==t[ncoin]*j)
  12. 12 {
  13. 13 m[ncoin][i]=j;
  14. 14 break;
  15. 15 }
  16. 16 }
  17. 17
  18. 18 for(int i=ncoin-1;i>=0;i--)
  19. 19 {
           //复制一遍
  20. 20 for(int j=0;j<=money;j++)
  21. 21 m[i][j]=m[i+1][j];
  22. 22 //修改到最佳
  23. 23 for(int j=money;j>=t[i];j--)//从后往前做
           /*好处:不用考虑前面已经用了该面值的硬币多少个。m数组记录的不是单一面值硬币用到的个数,而是所有面值硬币用到的总个数
            坏处:循环次数多了*/
  24. 24 for(int k=1;k<=coin[i];k++)
  25. 25 if((j-t[i]*k>=0)&&(m[i][j-t[i]*k]!=maxint)&&(m[i][j-t[i]*k]+k<m[i][j]))
  26. 26 m[i][j]=m[i][j-t[i]*k]+k;
  27. 27 }
  28. 28 if(m[0][money]==maxint)printf("-1");
  29. 29 else printf("%d\n",m[0][money]);
  30. 30
  31. 31 }
  32. 32
  33. 33 int main()
  34. 34 {
  35. 35
        //输入
        int ncoin;
  36. 36 scanf("%d",&ncoin);
  37. 37 int* t=(int *)malloc(sizeof(int)*ncoin);
  38. 38 int* coin=(int *)malloc(sizeof(int)*ncoin);
  39. 39 for(int i=0;i<ncoin;i++)
  40. 40 scanf("%d %d",&t[i],&coin[i]);
  41. 41 int money;
  42. 42 scanf("%d",&money);
        //准备
  43. 43 int** m=(int **)malloc(sizeof(int *)*ncoin);
  44. 44 for(int i=0;i<ncoin;i++)
  45. 45 m[i]=(int *)malloc(sizeof(int)*(money+1));
  46. 46 int** num=(int **)malloc(sizeof(int *)*ncoin);
  47. 47 for(int i=0;i<ncoin;i++)
  48. 48 num[i]=(int *)malloc(sizeof(int)*(money+1));
        //执行
  49. 49 getit(t,coin,ncoin-1,money,m);
        //打印过程
  50. 50 for(int i=0;i<ncoin;i++)
  51. 51 {
  52. 52 for(int j=0;j<=money;j++)
  53. 53 printf("%d ",m[i][j]);
  54. 54 printf("\n");
  55. 55 }
  56. 56 return 0;
  57. 57 }

 

 友情链接:直通硅谷  点职佳  北美留学生论坛

本站QQ群:前端 618073944 | Java 606181507 | Python 626812652 | C/C++ 612253063 | 微信 634508462 | 苹果 692586424 | C#/.net 182808419 | PHP 305140648 | 运维 608723728

W3xue 的所有内容仅供测试,对任何法律问题及风险不承担任何责任。通过使用本站内容随之而来的风险与本站无关。
关于我们  |  意见建议  |  捐助我们  |  报错有奖  |  广告合作、友情链接(目前9元/月)请联系QQ:27243702 沸活量
皖ICP备17017327号-2 皖公网安备34020702000426号