【问题标题】:Count number of ways to reach a score计算达到分数的方法数
【发布时间】:2020-02-20 21:43:57
【问题描述】:

我正在处理一项任务,现在我有一个数字我想知道有多少种方法可以使用 2,3,6 使用加法来达到这个数字,并且我可以尽可能多次地使用一个数字。

第一个例子:

Given number is 6
There are 3 ways to reach to this number:
2 +2 + 2 = 2*3
3 + 3 = 3*2
6

第二个例子:

Given number is 5
There are 2 ways to reach to this number:
2+3
3+2 (order matters here)

我在this link 的帮助下想出了以下代码:

static int count(int n) {
    // table[i] will store count of solutions for
    // value i.
    int table[] = new int[n + 1], i;

    // Base case (If given value is 0)
    table[0] = 1;

    // One by one consider given 3
    // moves and update the table[]
    // values after the index greater
    // than or equal to the value of
    // the picked move
    for (i = 2; i <= n; i++)
        table[i] += table[i - 2];
    for (i = 3; i <= n; i++)
        table[i] += table[i - 3];
    for (i = 6; i <= n; i++)
        table[i] += table[i - 6];

    return table[n];
}

此代码仅适用于第一个示例,但不适用于第二个示例,因为程序返回 1 而不是 2。

如何解决这个问题?

【问题讨论】:

  • 你说只使用了 2、3 和 6,但第一个例子是 6 * 1,所以你使用了 1,但你说这个例子是正确的?
  • @Nexevis,基本上 6* 1 只不过是使用 6 本身,所以正确。 2*3 也不过是 2+2+2,我会更新我的问题以避免混淆。
  • 所以基本上你只需要用这 3 个数字加起来就可以达到这个数字,但是你想用多少次就用多少次?
  • 定义“到达”一个数字。在您的第一个示例中,(2^3)-2 是达到 6 的另一种方式。
  • @Nexevis,是的,只添加了多少次,我会更新它

标签: java algorithm


【解决方案1】:

问题是您错过了诸如 2+6+2 之类的组合(其中较小的数字出现在较大的数字之后),因为您运行(例如)table[10] += table[10-2] 之前 table[8] += table[8-6] ,所以前者不考虑后者的结果。

要解决这个问题,请更改以下内容:

    for (i = 2; i <= n; i++)
        table[i] += table[i - 2];
    for (i = 3; i <= n; i++)
        table[i] += table[i - 3];
    for (i = 6; i <= n; i++)
        table[i] += table[i - 6];

到这里:

    for (i = 1; i <= n; i++) {
        if (i >= 2) {
            table[i] += table[i - 2];
        }
        if (i >= 3) {
            table[i] += table[i - 3];
        }
        if (i >= 6) {
            table[i] += table[i - 6];
        }
    }

以便您处理例如table[10] 仅在您完全处理后,例如table[8].

【讨论】:

  • 不错的解决方案,我错过了一件事情,我以为他/她也想要所有的序列。我删除了我的答案。
【解决方案2】:

您计算解决方案的数量,而不考虑元素的顺序。

例如,对于n = 52 + 3 仅计算一个元素,3 + 2 被视为相同的解决方案。

要获得您正在寻找的结果,您需要进行两项修改:

  1. 您必须记住所有相应的解决方案,而不是计算解决方案的数量。在这个级别,您不需要考虑顺序,只需记住一个解决方案对应的 2、3、6 的数量即可。这使您可以保持相同的程序结构,基本相同的高效算法。

  2. 1234563 .

对应的解数为:

N(x, y, z) = C(s, x) * C(s-x, y) * C(s-x-z, z)

其中s = x+y+zC(n, p) 是二项式系数

请注意,最后一个因子等于C(z, z) = 1

【讨论】:

    【解决方案3】:

    给你,

    对于输入 0 或 1,结果应为 0,因为使用 2、3 或 6 无法达到分数。

    我首先考虑所有tiny 数字( &lt;= 6 ),然后使用直循环查找所有其他数字(不再有 if 语句)。

    返回的类型很长,只是为了处理大输入。

      if (n == 0 || n == 1)
         return 0L;
    
      if (n == 2 || n == 3 || n == 4)
         return 1L;
    
      if (n == 5)
         return 2L;
    
      if (n == 6)
         return 3L;
    
      // Otherwise, n>6
    
      long[] table = new long[n + 1];
      table[0] = 1; // Base case
      table[1] = 0L; //
      table[2] = 1L; // 2
      table[3] = 1L; // 3
      table[4] = 1L; // 2+2
      table[5] = 2L; // 2+3, 3+2
      table[6] = 3L; // 2+2+2, 3+3, 6
    
      for (int i = 7; i <= n; i++)
         table[i] = table[i - 2] + table[i - 3] + table[i - 6];
    
      return table[n];
    

    【讨论】:

    • 我认为这根本不能回答问题。 OP 询问如何修复他/她的代码;这个答案只是提供了完全不同的代码。
    • @ruakh,我修改了答案。
    猜你喜欢
    • 1970-01-01
    • 2011-11-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-12-25
    • 2011-02-19
    • 2013-08-15
    • 1970-01-01
    相关资源
    最近更新 更多