【问题标题】:Recursive approach to finding out all the ways to change a €5 note?找出所有更改 5 欧元纸币的方法的递归方法?
【发布时间】:2019-10-23 10:48:11
【问题描述】:

我遇到了一个问题,即要找到所有可能的组合来更改 5 欧元纸币。我编写的程序未能产生正确数量的组合。

我的方法受到以下启发:

500可以分为200、200和100。 200可以分为100和100。 100可以分为50和50。

写完代码后,我意识到 100 也可以分为 5 个 20。这是我知道的一个错误,但我不知道如何使用我的方法来修复。

我的方法是一种递归方法,如下所示,它只是检查第一个数字并进行相应的除法。

这是我尝试过的:


public class Q1 {

    public static int counter;

    public static void main(String[] args) {

        divide(500);
        System.out.println(counter);

    }

    private static void divide(int x) {


        System.out.println("Dividing " + x);


        if(x == 1) {
            return;
        }

        counter++;

        int length = String.valueOf(x).length();

        int fd = Integer.parseInt(Integer.toString(x).substring(0, 1));
        String zeros;

        if(fd != 1) {
            zeros = Integer.toString(x).substring(1, length);
        }else {
            zeros = Integer.toString(x).substring(1, length-1);
        }


        if(fd == 5) {
            divide(Integer.parseInt(2 + "" + zeros));
            divide(Integer.parseInt(2 + "" + zeros));
            divide(Integer.parseInt(1 + "" + zeros));
        }else if(fd == 2) {
            divide(Integer.parseInt(1 + "" + zeros));
            divide(Integer.parseInt(1 + "" + zeros));
        }else if(fd == 1) {
            divide(Integer.parseInt(5 + "" + zeros));
            divide(Integer.parseInt(5 + "" + zeros));
        }


    }

}

例如使用上面的程序会错过

10 = 2 + 2 + 2 + 2 + 2

我知道like this one 已经存在可行的解决方案,但如果可能,我想保持我的方法。

使用该程序找出 500 美分的组合结果 388 种方式,其中正确答案是 6295435。有些东西告诉我,除了上面的例子之外,我忘记了其他东西。

【问题讨论】:

    标签: java combinations


    【解决方案1】:

    这里有一些提示,说明您为什么会得到错误的号码:

    确定所有可能性的正确方法


    为简单起见,尝试拆分 5 而不是 500。注意有4种可能性,即5 =

    1. 5
    2. 2 + 2 + 1
    3. 2 + 1 + 1 + 1
    4. 1 + 1 + 1 + 1 + 1

    现在尝试除以 10 而不是 500。 请注意,这可以分为 11 种不同的方式: 10 =

    1. 10
    2. 5 + 5
    3. 5 + 2 + 2 + 1
    4. 5 + 2 + 1 + 1 + 1
    5. 5 + 1 + 1 + 1 + 1 + 1
    6. 2 + 2 + 2 + 2 + 2
    7. 2 + 2 + 2 + 2 + 1 + 1
    8. 2 + 2 + 2 + 1 + 1 + 1 + 1
    9. 2 + 2 + 1 + 1 + 1 + 1 + 1 + 1
    10. 2 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1
    11. 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1

    此解决方案遵循以下模式: 您要拆分的数字 x 已经是答案。 通过将这些数字之一拆分为尽可能多的下一个最大数字,将最小数字的数量减少 1。总是忽略那些。如果只剩下一个(和一个)数字,请将 x 拆分为尽可能多的下一个最小数字并继续。

    例如 x = 10。那么:10 是最小的数字 -> 将其拆分为 5 + 5 -> 5 是最小的数字 -> 将其拆分为 2 + 2 + 1 -> 2 是最小的数字数字,因为忽略了 -> 将其拆分为 1 + 1 -> 我们有另一个 2,将其拆分为 1 + 1 (这等于解决方案 5 + 1 + 1 + 1 + 1 所以现在我们有 5除了一个数之外,只有一个数字。下一个最小的数字是 2)-> 将 x=10 拆分为 2 + 2 + 2 + 2 + 2 -> 2 是最小的数字;将其拆分为 1 + 1 -> 我们还有另外 2 ...

    这可以通过递归方式完成。

    代码中的问题


    您对除以 10 的示例所做的代码如下:

    1. 10分为5+5
    2. 前5分为2 + 2 + 1
    3. 这两个中的一个分为 1 + 1
    4. 另外两个分为1 + 1
    5. 现在,第二个 5 从除法到 5 + 5 被除法到 2 + 2 + 1
    6. 这两个中的一个分为1 + 1
    7. 另外两个分为1+1

    给它 7 种可能性的总分。 尝试将这 7 种可能性映射到上面的 11 种可能性,你数 10 =

    • 10 次
    • 5 + 5 一次
    • 5 + 2 + 2 + 1 两次
    • 5 + 2 + 1 + 1 + 1 两次
    • 5 + 1 + 1 + 1 + 1 + 1 两次

    并缺少其他 6 个选项。


    所以假设这个问题可以通过这样的方法来解决:

    10 = 5 + 5 -> 计算前 5 个,然后计算第二个 5

    是错误的,因为在这两种情况下,这都会导致 10 = 5 + 评估 5 的分布,只计算最终分布 10 中至少包含一个 5 的选项(计算多次,而没有 5 的分布是未评估)。


    另一个错误是代码说实际上存在 1 (1 = 1) 的情况下不可能分布 1。 另外,这个问题还不清楚

    • x 可以等于所有可能的整数吗? -> 4 不会在您的代码中拆分为 2 + 2
    • 是 1 + 1 + 2 与 1 + 2 + 1 和 2 + 1 + 1 不同的解吗?

    (我还没有资格在评论中提出这个问题)。


    保留递归方法只能通过一些重大更改来完成。上面说明了一种可能的方法。

    【讨论】:

      猜你喜欢
      • 2023-03-02
      • 1970-01-01
      • 2020-08-02
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-03-14
      • 2021-10-06
      • 2020-03-29
      相关资源
      最近更新 更多