繁体   English   中英

计算达到分数的方法数

[英]Count number of ways to reach a score

我正在执行一项任务,我现在有一个数字,我想知道使用 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)

我在此链接的帮助下提出了以下代码:

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+6+2 之类的组合(其中较小的数字出现在较大的数字之后),因为您table[8] += table[8-6]之前运行(例如) 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]

干得好,

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

我首先考虑所有的tiny数字( <= 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];

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

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

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

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

  2. 然后,对于每个特定解(x, y, z) ,其中x, y, z是与 2, 3, 6 相关联的多重性,您必须评估通过修改获得的可能性N(x, y, z)的数量元素的顺序。

对应的解数为:

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM