[英]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 = 5
, 2 + 3
仅对一个元素计数, 3 + 2
被视为相同的解决方案。
要获得您正在寻找的结果,您需要进行两次修改:
您必须记住所有相应的解决方案,而不是计算解决方案的数量。 在这个级别,你不需要考虑顺序,只需记住一个解决方案对应的 2、3、6 的数字。 这允许您保持相同的程序结构,基本相同的高效算法。
然后,对于每个特定解(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+z
和C(n, p)
是二项式系数
请注意,最后一个因子等于C(z, z) = 1
。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.