function pay() {
var waysOfPaying= 0;
for (e = 0; e < 10; e++) {
for (d = 0; d < 13; d++) {
for (c = 0; c < 16; c++) {
for (b = 0; b < 16; b++) {
for (a = 0; a < 16; a++) {
if ((a + b + c + d + e <= 15) && (a + (2 * b) + (3 * c) + (4 * d) + (5 * e) == 49)) {
waysOfPaying++;
}
}
}
}
}
}
return waysOfPaying % 1000 ;
}
我的代码给出的答案是333但是正确答案是714.我做错了什么?
答案 0 :(得分:2)
您的算法面向每个硬币的价值。问题在于它失去了秩序的重要性:它发现9个值为5的硬币加上1个值为4的硬币加起来为49.但它错过了8个硬币值为5的事实,其次是乘以1,值为4,接着是另外5,也加起来为49。
最初的问题是基于从太空移动到太空,建立一个移动到方格50的轨迹。关注你的位置,而不是跳跃值。想想在每个空间做出的决定: - 你在50号太空吗?如果是这样,你找到了一条有效的踪迹,算上它。 - 你过了49号广场,或者你有15次搬到这里?如果是,则该路径结束,并且没有任何进一步的跳跃。 - 如果不是,则可以进行5次可能的移动:跳过1,2,3,4或5个空格。在每一个之后,再次评估你的位置。
提示:使用递归函数模拟您在空间上的操作。
答案 1 :(得分:2)
此问题也发布在cs.stackexchange中。 我从那里添加了我的答案副本:
我会用动态编程来解决它。无论如何,你的代码对我来说很好。您将查看所有选项,并计算满足条件的那些选项。
我运行了你的脚本,我看到选项的数量正好是333.如果这真的是答案,那么为什么在这个问题中你被要求给出最后三位数?
我想,也许你需要计算选项并考虑内在的顺序。
例如:5,5,5,5,5,5,5,5,5,4将作为选项计算,并且4,5,5,5,5,5,5,5,5 ,5将被视为另一种选择。
在这种情况下,选项的数量会更高,并且要求最后三位数是有意义的。
您可以通过计算满足条件的每个元组(a,b,c,d,e)的排列数(注意有相同的元素),轻松地将代码更改为此版本的问题。它比回顾所有选项更有效率。
答案 2 :(得分:0)
正如人们之前所指出的那样,由于订单很重要,您想要回答的问题与所述问题不同。你给出的解决方案是正确的,没有排列(333)。但是,我不认为尝试所有选项都是解决这个问题的好方法。
如果您有兴趣看到可以在JavaScript中实现,请参阅下文:
function pay (target, maxCoins, partial) {
function sumArray (array) {
var sum = 0;
for (var i = 0; i < array.length; i++) {
sum += array[i];
}
return sum;
}
if (typeof target === 'undefined')
target = 49;
if (typeof maxCoins === 'undefined')
maxCoins = 15;
if (!partial)
partial = [];
var sum = sumArray(partial);
if (sum === target) {
return 1;
} else if (sum < target && partial.length < maxCoins) {
var childSolutions = 0;
for (var next = 1; next <= 5; next++) {
var copy = partial.slice(0);
copy.push(next);
childSolutions += pay(target, copy);
}
return childSolutions % 1000;
}
return 0;
}
不知道这实际需要多长时间才能运行(我在几个小时后放弃了!)。有效解决问题的诀窍是做你做过的事情,但对于你找到的每个解决方案,找出硬币可以重新排列的方式。幸运的是有一个well-known formula for this(参见“Multiset位”)。下面是您的代码如何适应包含排列..
var factorials = [1 , 2, 6, 24, 120, 720, 5040, 40320, 362880, 3628800, 39916800, 479001600, 6227020800, 87178291200, 1307674368000];
function permutations (a, b, c, d, e) {
var n = a + b + c + d + e;
var base = 1;
for (var i = 0; i < 5; i++) {
var arg = arguments[i];
if (arg > 0)
base *= factorials[arg - 1];
}
return n < 1 ? 1 : factorials[n - 1] / base ;
}
function pay() {
var a, b, c, d, e,
waysOfPaying = 0;
for (e = 0; e < 10; e++) {
for (d = 0; d < 13; d++) {
for (c = 0; c < 16; c++) {
for (b = 0; b < 16; b++) {
for (a = 0; a < 16; a++) {
if ((a + b + c + d + e <= 15) && (a + (2 * b) + (3 * c) + (4 * d) + (5 * e) == 49)) {
waysOfPaying += permutations(a, b, c, d, e);
}
}
}
}
}
}
return waysOfPaying % 1000 ;
}
如果您运行,则为您提供您期望的值714。