我正在尝试编写一个函数来探索数字的所有可能组合,以数组形式给出,希望找到加起来一定数量的最小数字组,并将其作为参数传递。
这是我一直在做的事情,这似乎适用于一些但不是所有情况;
我选择一个数字,从总和中减去它,并将新的总和传递给函数,数组的限制保持不变,这使我可以选择重新选择数字,
在第二次调用中,我传递了新的总和,即总和减去当前选择的数字,但我将数组缩小了一个,这意味着我不会再选择相同的数字。
然而,我已经意识到我并没有涵盖所有选择,因为无论如何我假设任何数字对解决方案都至关重要,但我不知道要通过哪些参数来覆盖第三个选项,它不是选择数字,意味着我不会从总和中减去数字,而是缩小数组的大小。
你的帮助将不胜感激,顺便说一下,我正在用C语言写作。
int howManyCoins(int*coins,int size,int sum)
{
return howManyCoins_aux(coins,size,sum,size-1);
}
int howManyCoins_aux(int*coins,int size, int sum,int chosen)
{
if (sum==0)return 1;
if (sum<0)return 0;
if (chosen==0) return 0;
if (coins[chosen]>sum) return 0;
int res1=0,res2=0,best_solution=0;
for (int i=chosen;i>=0;i--)
{
res1+=howManyCoins_aux(coins,size,sum-coins[i],chosen);
res2+=howManyCoins_aux(coins,size,sum-coins[i],chosen-1);
if(!(res1+res2)) best_solution=0;
else if (res1==0) best_solution=res2;
else if (res2==0) best_solution=res1;
else best_solution=res2>res1?res1:res2;
}
return best_solution;
}
答案 0 :(得分:0)
如果要检查所有可能的值,可以使用位数组。如果给定的数组足够短,则可以使用整数(或长整数)作为位数组。 现在,让a成为你的数组,然后为每个索引n: 如果且只有位数组的位n被设置,则[n]处于组合中。
答案 1 :(得分:0)
您可以简化您的选择:选择硬币并重新选择硬币或不选择硬币(递归将涵盖所有选项)
替换:
res1+=howManyCoins_aux(coins,size,sum-coins[i],chosen);
res2+=howManyCoins_aux(coins,size,sum-coins[i],chosen-1);
与
res1 = howManyCoins_aux(coins, size, sum-coins[i], chosen);
res2 = howManyCoins_aux(coins, size, sum, chosen-1);
如果你只能挑选每枚硬币中的一个:(这是change-making problem)
res1 = howManyCoins_aux(coins, size, sum-coins[i], chosen-1);
res2 = howManyCoins_aux(coins, size, sum, chosen-1);
你的算法有点不清楚,我认为有很多重复。您可以摆脱for循环,并将您的功能更改为:(未经测试)
int howManyCoins_aux(int *coins, int size, int sum, int chosen, int pos)
{
if (sum == 0) return chosen;
if (sum < 0 || pos == size) return 9999999;
int res1 = 9999999;
if (coins[pos] >= sum)
res1 = howManyCoins_aux(coins, size, sum-coins[pos], chosen+1, pos);
int res2 = howManyCoins_aux(coins, size, sum, chosen, pos+1);
return min(res1, res2);
}
话虽如此,递归可能不是可行的方法(即使在小型数据集上也需要很长时间)。听起来像integer programming。在链接中有一些解决方案可供选择。
答案 2 :(得分:0)
这听起来像是子集求和问题的变体。由于您只考虑正数,因此如果您保留另一个数据结构来跟踪与每个可能值相加的数字集,那么像here所述的动态编程方法可能会起作用。