异常的多项式时间算法

时间:2015-04-13 19:06:23

标签: algorithm

我需要设计一个接受正整数k作为输入的算法,并找出关系=和<之后的k个对象的排列数。 例如:如果k = 3,那么十三种可能的安排是:

x=y=z
x=y<z
x<y=z
x<y<z
x<z<y
x=z<y
y<x=z
y<x<z
y<z<x
y=z<x
z<x<y
z<y<x
z<x=y

该算法适用于任何k,并且应该在多项式时间内运行。

1 个答案:

答案 0 :(得分:1)

以下C#代码基于Wikipedia page

的递归关系
a(n) = Sum {i from 1 to n} (n i) a(n - i)

该算法使用动态编程迭代计算二项式系数和有序贝尔数。 k变量的可能表达式数量为k-th Ordered Bell Number:

int GetNumberOfExpressions(int k)
{
    //Holds Ordered Bell Numbers calculated so far
    int[] a = new int[k + 1];

    //Contains one row of Pascal's triangle
    int[] binomial = new int[k + 1];

    //Initialize the recurrence
    a[0] = 1;
    binomial[0] = 1;

    //Successively calculate a_1 thru a_k
    for (int i = 1; i <= k; ++i)
    {
        //calculate i-th row of Pascal's triangle
        binomial[i] = 1;
        for (int j = i - 1; j >= 1; --j)
            binomial[j] = binomial[j] + binomial[j - 1];

        //calculate a_i
        for (int j = 1; j <= i; ++j)
            a[i] += binomial[j] * a[i - j];
    }

    return a[k];
}

此算法的时间复杂度为O(k^2),空间复杂度为O(k)