让M(n, k)成为所有具有最大可能因子n、k个不同因子的乘积之和,其中顺序无关紧要。例如,M(5, 3) = 225,因为有10种这样的乘法,它们是1*2*3、1*2*4、1*2*5、1*3*4、1*3*5、1*4*5、2*3*4、2*3*5、2*4*5和3*4*5,它们之和为225。可以轻松地注意到,有C(n,k)这样的乘法,对应于从n个可能对象中选择k个对象的方式数量。在上面的例子中,C(5,3) = 10,确实有这样的10个乘法。
这个问题也可以被看作是包含恰好k个0的可能的大小为n的集合,其中每个不包含0的单元格在内部都有其索引+1的值。例如,一种可能的这样的集合是{0,2,3,0,5}。从这里开始,需要将集合中与0不同的值相乘。
我的方法是一个递归算法。类似于上述定义M(n, k),我定义M(n,j,k)为具有n作为最大可能因子及j作为最小可能因子的恰好k个不同因子的所有可能乘积之和。因此,如果使用M(n,1,k)计算出所需的值,则我的方法将得到期望的值。因此,我从M(n,1,k)开始递归,使用Java编写以下代码:
如果 k=1,那么使用此求和的原因,我将通过一个例子来解释: 假设我们从1*2开始。现在我们需要第三个因子,可以是3、4或5中的任何一个。因为所有的乘法:1*2*3、1*2*4、1*2*5都是有效的,所以我们可以返回1*2*(3+4+5) = 1*2*sum(3,5) = 24。
类似的逻辑也可以解释出系数"i",它在M(n,j+1,k-1)旁边。 假设我们现在只有一个因子2。因此我们需要两个更多的因子,所以我们将2乘以接下来的迭代,应该得到: 2*(3*sum(4,5) + 4*sum(5,5)) 然而,由于某种我还不能解释的原因,代码不起作用。它返回错误的值,并且还有“return”问题,导致函数没有返回任何内容,我不知道为什么。
这就是我在这里发布这个问题的原因,希望有人能帮助我。要么通过修复此代码,要么分享他自己的代码。解释我的错误将是最受欢迎的。
提前感谢您,对于这个非常长的问题,表示抱歉, Matan。
以下是我修改后的代码,解决了这个问题。如果有需要的话,可以参考一下 :) 祝使用愉快!
这个问题也可以被看作是包含恰好k个0的可能的大小为n的集合,其中每个不包含0的单元格在内部都有其索引+1的值。例如,一种可能的这样的集合是{0,2,3,0,5}。从这里开始,需要将集合中与0不同的值相乘。
我的方法是一个递归算法。类似于上述定义M(n, k),我定义M(n,j,k)为具有n作为最大可能因子及j作为最小可能因子的恰好k个不同因子的所有可能乘积之和。因此,如果使用M(n,1,k)计算出所需的值,则我的方法将得到期望的值。因此,我从M(n,1,k)开始递归,使用Java编写以下代码:
public static long M (long n, long j, long k)
{
if (k==1)
return usefulFunctions.sum(j, n);
for (long i=j;i<=n-k+1+1;i++)
return i*M(n,i+1,k-1);
}
代码解释:
从例如n=5,j=1,k=3开始,只要我们需要更多因子(k>=1),算法将继续运行,并通过for循环确保只运行不同的因子,随着添加更多因子,增加最小可能值j。循环运行并减少所需因子的数量,当它们被“添加”时,这是通过应用M(n,j+1,k-1)实现的。 j+1 确保因子是不同的,因为因子的最小值增加,k-1 表示我们需要添加1个因子。
函数'sum(j,n)'返回所有数字的总和,从j开始到n结束,因此sum(1,10)=55。 这是通过一个适当、优雅且简单的数学公式完成的,没有循环:sum(j,n) = (n+1)*n/2 - (i-1)*i/2
public static long sum (long i, long n)
{
final long s1 = n * (n + 1) / 2;
final long s2 = i * (i - 1) / 2;
return s1 - s2 ;
}
如果 k=1,那么使用此求和的原因,我将通过一个例子来解释: 假设我们从1*2开始。现在我们需要第三个因子,可以是3、4或5中的任何一个。因为所有的乘法:1*2*3、1*2*4、1*2*5都是有效的,所以我们可以返回1*2*(3+4+5) = 1*2*sum(3,5) = 24。
类似的逻辑也可以解释出系数"i",它在M(n,j+1,k-1)旁边。 假设我们现在只有一个因子2。因此我们需要两个更多的因子,所以我们将2乘以接下来的迭代,应该得到: 2*(3*sum(4,5) + 4*sum(5,5)) 然而,由于某种我还不能解释的原因,代码不起作用。它返回错误的值,并且还有“return”问题,导致函数没有返回任何内容,我不知道为什么。
这就是我在这里发布这个问题的原因,希望有人能帮助我。要么通过修复此代码,要么分享他自己的代码。解释我的错误将是最受欢迎的。
提前感谢您,对于这个非常长的问题,表示抱歉, Matan。
-----------------------EDIT------------------------
以下是我修改后的代码,解决了这个问题。如果有需要的话,可以参考一下 :) 祝使用愉快!
public static long M(long n, long j, long k)
{
if (k == 0)
return 0;
if (k == 1)
return sum(j,n);
else
{
long summation = 0;
for (long i=j; i<=n; i++)
summation += i*M(n, i+1, k-1);
return summation;
}
}
double s1 = n/2*(n+1);
这行代码可能存在一个错误。如果n
等于1
,请检查s1
的值。 - antonpps1
和s2
被声明为双精度浮点数?你只是想计算两个整数之间的和。 - QBrutelong n = 5
表示行double x = n / 2
将使您的x
值为 2.0 而不是 2.5。 - antonpp