k个不同因子的可能乘法,具有最大可能因子n

时间:2015-05-08 14:01:56

标签: java arrays algorithm math

M(n,k) k 的所有可能乘法 最大可能因素 n 的不同因素,其中订单无关

例如, M(5,3)= 225 ,因为:

  • 1 * 2 * 3 = 6
  • 1 * 2 * 4 = 8
  • 1 * 2 * 5 = 10
  • 1 * 3 * 4 = 12
  • 1 * 3 * 5 = 15
  • 1 * 4 * 5 = 20
  • 2 * 3 * 4 = 24
  • 2 * 3 * 5 = 30
  • 2 * 4 * 5 = 40
  • 3 * 4 * 5 = 60

6 + 8 + 10 + 12 + 15 + 20 + 24 + 30 + 40 + 60 = 225。

可以很容易地注意到 C(n,k)这样的乘法,对应于 n中可以选择 k 对象的方式的数量可能的对象。在上面的例子中, C(5,3)= 10 并且确实存在10次这样的乘法,如上所述。

这个问题也可以看作是可能的 n大小的集合,其中包含 k 0's ,其中每个不包含0的单元格具有其值里面有指数+ 1 。例如,一个可能的这样的集合是 {0,2,3,0,5}。从这里开始,需要将集合中不同于0的值相乘。

我的方法是递归算法。类似于上面的定义 M(n,k),我将 M(n,j,k)定义为精确 k 的所有可能乘法的总和具有最大可能因子的因素 n AND SMALLEST 可能因素 j 。因此,如果继续运行,我的方法将产生所需的值 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 的所有数字之和的值,所以的总和(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

类似的逻辑解释 M(n,j + 1,k-1)旁边的系数“i” 说我们现在有唯一的因素2.因此我们还需要2个因子,所以我们将2乘以下一个迭代,这应该导致: 2 *(3 *总和(4,5)+ 4 *总和(5,5))

但是,由于我无法解释的原因,代码不起作用。它返回错误的值,并且还有“返回”问题导致函数不返回任何内容,不知道原因。

这就是我在这里发布这个问题的原因,希望有人能帮助我。通过修复此代码或共享他自己的代码。解释我出错的地方将是最明显的。

非常感谢,对这个很长的问题感到抱歉, 马坦。

-----------------------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;
    }
}

3 个答案:

答案 0 :(得分:2)

你的sum函数有问题:这是正确的公式:

public static long sum (long i, long n)
    {
        double s1 = n*(n+1)/2;
        double s2 = i*(i-1)/2;
        return (long)(s1-s2);
    }

这里有完整的解决方案:

    static int n = 5; 
    static long k = 3;
// no need to add n and k them inside your M function cause they are fixed.
    public static long M (long start) // start = 1
    {
        if(start > k) // if start is superior to k : like your example going from 1..3 , then you return 0
            return 0;
        int res = 0; // res of your function
        for(long i=start+1;i<n;i++){
            res+=start*i*sum(i+1,n); // here you take for example 1*2*sum(3,5) + 1*3*sum(4,5).... ect

        }

        return res+M(start+1); // return res and start again from start+1 wich would be 2.

    }
    public static long sum (long i, long n)
    {
        if(i>n)
            return 0;
        double s1 = n*(n+1)/2;
        double s2 = i*(i-1)/2;
        return (long)(s1-s2);
    }
    public static void main(String[] args) {
        System.out.println(M(1));
    }

希望有所帮助

答案 1 :(得分:2)

我不确定你的算法,但你肯定搞砸了你的sum函数。您遇到的问题与类型转换和整数除法有关。尝试这样的事情:

public static long sum (long i, long n)
{
    final long s1 = n * (n + 1) / 2;
    final long s2 = (i * i - i) / 2;
    return s1 - s2 ;
}

答案 2 :(得分:2)

我看到你得到了你的答案,我真的很喜欢你的算法,但我无法控制自己发布更好的算法。这是想法

M(n,k) = coefficient of x^k in (1+x)(1+2*x)(1+3*x)...(1+n*x)

你可以通过除法和征服算法Click Here来解决上述表达式,找到如何将上面的表达式相乘并以ax^n + bx^(n-1)....+c

的形式得到多项式函数

整体算法时间复杂度为O(n * log^2 n)

以上算法的最佳部分是

in the attempt of finding solution for M(n,k) , u will find solution for M(n,x) where 1<=x<=n

我希望知道:)