java - 使用动态规划改变硬币

标签 java dynamic-programming

换硬币是一个很受欢迎的面试问题。本质上,这个问题意味着给定一组硬币面额和总数,如果每种面额的硬币都有无限供应,那么有多少种方法可以获得总数。

这是我的代码。 逻辑是每次我选择一枚硬币时,问题都会减少到解决总数减去硬币的问题。

public static int numberOfWays(int total, int[] options){

        int[][] memo = new int[options.length][total+1];

        for (int i = 0; i <memo.length ; i++) {

            for (int j = 0; j <memo[i].length ; j++) {

                if(i == 0)  memo[i][j] = 1;
                else if(options[i] > j ) memo[i][j] = memo[i-1][j];
                else memo[i][j] = memo[i-1][j] + memo[i][j - options[i]];
            }
        }
        return memo[options.length-1][total];
    }

这适用于 total = 5 和 options = 1, 2, 3 的测试用例 但失败 total = 10 and options = 2, 5, 3, 6

谁能帮助我理解我做错了什么。

最佳答案

首先,最好写出每个数组元素代表什么的声明:

memo[i][j] represents how many ways to make the total amount j given only coins in denominations options[0], options[1], ..., options[i].

现在,您似乎从中推导出了一些定律:

  1. memo[0][j]1对于所有 j
  2. i大于 0,memo[i][j]memo[i-1][j]相同每当options[i] > j
  3. i大于 0,memo[i][j]memo[i-1][j] + memo[i][j - options[i]]每当options[i] <= j

你的问题是这些定律中的第一个是不正确的。 (后面两个是)

声明“memo[0][j] is 1 for all j”仅在options[0] 时成立是1 .如果options[0]不是 1 , 然后 memo[0][j]j 时为 1是 options[0] 的倍数, 如果不是则为 0。仅使用面额硬币 2 ,你赚不到 5 美分,所以你应该有(第二组数据)memo[0][5] == 0 , 但你的程序说 memo[0][5] == 1 .然后,这会抛出所有后续计算。

所以我会修改你的程序说:

            if(i == 0) { if (j % options[i] == 0) memo[i][j] = 1;
                         else memo[i][j] = 0; }
            else if(options[i] > j ) memo[i][j] = memo[i-1][j];
            else memo[i][j] = memo[i-1][j] + memo[i][j - options[i]];

(尽管就纯粹的文体注释而言,我发现 if/else 即使是单个语句也不使用大括号的语句是在询问错误)

关于java - 使用动态规划改变硬币,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36696667/

相关文章:

java - 兰伯特等角圆锥 map 投影在java中获取网格的x,y值

java - 如何在 LWJGL 3 中使用 glfwSetWindowUserPointer?

java - 我需要的任务的有效解决方案

java - 尽管不是堆栈的一部分,字符串中最长回文的输出仍会正确打印

c++ - 自上而下的动态编程 VS 递归朴素解决方案。检查运行时执行

java - 如何使用tools.jar编译方法打印Java编译器错误日志?

java - 在 Wildfly 服务器上配置 MariaDB 驱动程序时出错

java - 尝试使用 apache poi 在 Excel 上写入 WCC 搜索结果时出错

java - 这段代码如何以及为何起作用?找到将一个单词更改为另一个单词的最少步骤数

recursion - 用动态规划编写递归算法