AlgorithmforCountingtheNumberofCombinationstoForm100我遇到了一个棘手的情况,我需要根据不同的因素计算形成100的组合数。这些是样本输入1:(2-10-20)这意味着输出将是[40,60][50,50][60,40]这里[30,70],[20,60]是无效的,因为distance大于20。示例输入2:[2-5-20][40,60][45,55][50,50][55,45][60,40]如果可以,我将不胜感激指引我正确的方向。干杯。我希望这不是一道作业题!def组合(n:Int,step:Int,distance:Int,sum:Int=100):List[List[Int]]=if(n==1)List(List(sum))elsefor{first(first-x).abs如果需要将最大距离N除以100除以2,则组合中的最小值为100/2-N/2如果需要将3个值除以100,则最大值距离为N,这变得更加棘手。3个值的平均值为100/3,但是如果其中一个值远低于这个平均值,其他值只能略大于这个平均值,也就是说最小值不是平均值减去最大距离二,但可能是100/3–2N/3通常,对于M的值,这变成100/M–(M-1)N/M。可以简化为(100–(M-1)N)/M。同样,我们可以计算出最高可能值:(100+(M-1)N)/M。这为您提供了第一个值的组合范围。要确定第二个值的范围,您必须考虑以下约束:第一个约束不是问题。第二个是。假设我们将100除以3除以最大距离30,使用10的倍数,如前所述,最小值为:(100-(3-1)30)/3->13->四舍五入到10的下一个倍数->20的最大值为(100+(3-1)30)/3->53->舍入为之前10的倍数->50,因此对于第一个值,我们应该迭代20、30、40和50。假设我们选择20。这为其他2个值留下80。我们再次将80分配给最大距离为30的2个值,这给出:min:(80-(2-1)30)/2->25->rounding->30max:(80+(2-1)30)/2->55->舍入->50第二个约束是我们不希望与第一个值相比的距离大于30。这至少是-10,最大值是50。现在取两个域之间的交集->30到50,第二个值迭代30、40、50。然后为下一个值重复此操作。编辑:我在伪代码中添加了算法以使其更清楚:calculateRange(vector,remainingsum,nofremainingvalues,multiple,maxdistance){if(remainingsum==0){//此时nofremainingvalues也应该为零//找到解决方案printvectorreturn;}minvalueaccordingdistribution=(remainingsum-(nofremainingvalues-1)*maxdistance)/nofremaingvalues;maxvalueaccordingdistribution=(remainingsum+(nofremainingvalues-1)*maxdistance)/nofremaingvalues;;maxvalueaccordingdistance=min(valuesinvector)+maxdistance;minvalue=min(minvalueaccordingdistribution,minvalueaccordingdistance);maxvalue=max(minvalueaccordingdistribution,minvalueaccordingdistance);for(value=minvalue;value,假设N-组合数M-倍数D-最大可能距离所以,组合中的可能值可以是M,2M,3M等。你需要生成这个集合然后从集合中的第一个元素,并尝试从集合中相同的Select值开始寻找接下来的两个元素(假设它们应该比第一个/第二个值小D)。因此对于3-10-30的i/p将创建一组10,20,30,40,50,60,70,80,90作为可能的值,从10开始,第二个值选择必须是20,30,40,50(D<30)现在从20,30,40,50的集合中选择第二个值并尝试获取下一个值,依此类推如果使用递归,解决方案会简单得多。你必须从MIN&MAX索引中的可能值列表中找到N个值。因此,请尝试MIN索引处的第一个值(到MAX索引)。假设我们选择了X索引处的值。对于每个第一个值,尝试从列表中找到MIN=X+1和MAX的N-1个值。当M=1且N足够大时,性能最差。是所有附加因素之间的距离,还是它们之间的距离?例如,对于3-10-20,[20-40-60]是有效答案吗?我将假设后者,但可以非常简单地修改下面的解决方案以适用于前者。无论如何,要走的路是从您可以管理的最极端的答案(一种)开始,然后逐步解决答案,直到找到另一种最极端的答案。让我们尝试使数字尽可能低,除了最后一个数字尽可能高(假设其他数字都很低)。将公约数除以d,再除以100,得到S=100/d。这很好地量化了我们的问题。现在我们有一个间距最多为s的约束,除非我们将其转换为许多量化步长,n=s/d。现在假设我们有M个样本,i1...iM并写下约束条件:i1+i2+i3+...+iM=S0我们可以求解第一个方程以获得另一个iM。现在,如果我们让一切尽可能相似:i1=i2=...=iM=IM*I=SI=S/M太棒了——我们有了起点!(如果I是一个分数,那么前几个I和剩下的I+1)现在我们试着依次遍历每个变量:for(i1=I-1by-1untilcriteriafails)sumneedstoaddtoS-i1i2>=i1i2好吧,看这里——我们有一个递归算法!我们只是走过去阅读答案。当然,我们可以走i1而不是步行。如果您需要打印答案,您也可以这样做。如果您只需要计算它们,请注意计数是对称的,因此只需将倒计时得到的答案加倍即可。(如果不是所有值开始时都相同,您还有一个校正因子-如果有些值是I,有些值是I+1,则您需要考虑到这一点,我不会在这里这样做。)编辑:如果范围是每个值都必须在范围内,而不是所有值0条件下,你有max(i1,i2,...,iM)-min(i1,i2,...,iM)但这给出相同的递归条件,除了不是在i2(或转向它的任何其他变量)上添加约束,我们将我们选择投射到混合中的那些项的最大值和最小值传递。输入:(2-10-20)将数字(50,50)2除以参数1以检查差异规则是否允许此组合。如果它违反规则,则停止,如果允许,则将此组合添加到结果列表中Ex:abs(50-50)<20,所以没关系3将第一个值增加参数2,减少第一个值通过参数2以上两个值是C#学习教程:用于计算组成100的组合个数的算法。如果对大家有用,需要详细了解C#学习教程,希望大家点赞更多关注---转2。点击此文章来自网络收藏,不代表立场,如涉及侵权,请点击右侧联系管理员删除。如需转载请注明出处:
