• 换钱的最小货币数-Java:原问题的经典动态规划方法


    分享一个大牛的人工智能教程。零基础!通俗易懂!风趣幽默!希望你也加入到人工智能的队伍中来!请轻击人工智能教程

    1. package live.every.day.ProgrammingDesign.CodingInterviewGuide.RecursionAndDynamicPrograming;
    2. /**
    3. * 换钱的最少货币数
    4. *
    5. * 【题目】
    6. * 给定数组arr,arr中所有的值都为正数且不重复。每个值代表一种面值的货币,每种面值的货币可以使用任意张,再给定一个整数aim
    7. * 代表要找的钱数,求组成aim的最少货币数。
    8. *
    9. * 【补充题目】
    10. * 给定数组arr,arr中所有的值都为正数。每个值仅代表一张钱的面值,再给定一个整数aim代表要找的钱数,求组成aim的最少货币数。
    11. *
    12. * 【难度】
    13. * 中等
    14. *
    15. * 【解答】
    16. * 原问题的经典动态规划方法。如果arr的长度为N,生成行数为N、列数为aim+1的动态规划表的dp。dp[i][j]的含义是,在可以任意
    17. * 使用arr[0..i]货币的情况下,组成j所需的最小张数。根据这个定义,dp[i][j]的值按如下方式计算:
    18. * 1、dp[0..N-1][0]的值(即dp矩阵中第一列的值)表示找的钱数为0时需要的最小张数,钱数为0时,完全不需要任何货币,所以
    19. * 全设为0即可。
    20. * 2、dp[0][0..aim]的值(即dp矩阵中第一行的值)表示只能使用arr[0]货币的情况下,找某个钱数的最小张数。比如,arr[0]=2,
    21. * 那么能找开的钱数为2,4,6,8,...所以令dp[0][2]=1,dp[0][4]=2,dp[0][6]=3,...第一行其他位置所代表的钱数一律找不开,
    22. * 所以一律设为32位整数的最大值,我们把这个值记为max。
    23. * 3、剩下的位置依次从左到右,再从上到下计算。假设计算到位置(i,j),dp[i][j]的值可能来自下面的情况。
    24. * 完全不使用当前货币arr[i]情况下的最少张数,即dp[i-1][j]的值。
    25. * 只使用1张当前货币arr[i]情况下的最少张数,即dp[i-1][j-arr[i]]+1。
    26. * 只使用2张当前货币arr[i]情况下的最少张数,即dp[i-1][j-2*arr[i]]+2。
    27. * 只使用3张当前货币arr[i]情况下的最少张数,即dp[i-1][j-3*arr[i]]+3。
    28. * 所有的情况中,最终取张数最小的,所以
    29. * dp[i][j]=min{dp[i-1][j-k*arr[i]]+k(0<=k)}
    30. * =>dp[i][j]=min{dp[i-1][j],min{dp[i-1][j-x*arr[i]]+x(1<=x)}}
    31. * =>dp[i][j]=min{dp[i-1][j],min{dp[i-1][j-arr[i]-y*arr[i]]+y+1(0<=y)}}
    32. * 又有min{dp[i-1][j-arr[i]-y*arr[i]]+y(0<=y)} => dp[i][j-arr[i]],所以,最终有:
    33. * dp[i][j]=min{dp[i-1][j],dp[i][j-arr[i]]+1}。如果j-arr[i]<0,即发生越界了,说明arr[i]太大,用一张都会超过
    34. * 钱数j,令dp[i][j]=dp[i-1][j]即可。
    35. *
    36. * 具体过程请参看如下代码中的minCoins1方法,整个过程的时间复杂度与额外空间复杂度都为O(N*aim),N为arr的长度。
    37. *
    38. * @author Created by LiveEveryDay
    39. */
    40. public class ChangeMoneyMinCurrencyNumber1 {
    41. public static int minCoins1(int[] arr, int aim) {
    42. if (arr == null || arr.length == 0 || aim < 0) {
    43. return -1;
    44. }
    45. int n = arr.length;
    46. int max = Integer.MAX_VALUE;
    47. int[][] dp = new int[n][aim + 1];
    48. for (int j = 1; j <= aim; j++) {
    49. dp[0][j] = max;
    50. if (j - arr[0] >= 0 && dp[0][j - arr[0]] != max) {
    51. dp[0][j] = dp[0][j - arr[0]] + 1;
    52. }
    53. }
    54. int left = 0;
    55. for (int i = 1; i < n; i++) {
    56. for (int j = 1; j <= aim; j++) {
    57. left = max;
    58. if (j - arr[i] >= 0 && dp[i][j - arr[i]] != max) {
    59. left = dp[i][j - arr[i]] + 1;
    60. }
    61. dp[i][j] = Math.min(left, dp[i - 1][j]);
    62. }
    63. }
    64. return dp[n - 1][aim] != max ? dp[n - 1][aim] : -1;
    65. }
    66. public static void main(String[] args) {
    67. int[] arr = {2, 5, 3};
    68. int aim = 10;
    69. System.out.printf("The min currency number is: %d", minCoins1(arr, aim));
    70. }
    71. }
    72. // ------ Output ------
    73. /*
    74. The min currency number is: 2
    75. */
  • 相关阅读:
    ONLYOFFICE8.1版本桌面编辑器测评
    宾夕法尼亚州立大学:探索量子AI如何加速治愈癌症
    Unity 性能优化Shader分析处理函数:ShaderUtil.GetShaderGlobalKeywords用法
    什么是Java中的设计模式?请列举几种常见的设计模式
    信息安全技术
    概念解析 | LoRA:低秩矩阵分解在神经网络微调中的作用
    java 找不到或无法加载主类
    猿创征文|Hadoop大数据技术
    Express框架---中间件
    CDH大数据平台 /bin/sh: mysql_config: command not found
  • 原文地址:https://blog.csdn.net/chimomo/article/details/127837377