具有 k 个部分的排序和非排序整数分区

TTh*_*end 2 arrays algorithm combinations ranking integer-partition

对于正整数nk,令“ n的k分区”为加起来为n 的k个不同正整数的排序列表,并令给定的n的k分区的“排名”为其在列表中的位置。所有这些列表按字典顺序排序的列表,从 0 开始。

例如,有两个 5 的 2 分区(n  = 5,k  = 2):[1,4] 和 [2,3]。由于 [1,4] 按字典顺序位于 [2,3] 之前,因此 [1,4] 的排名为 0,[2,3] 的排名为 1。

所以,我希望能够做两件事:

  • 给定nknk分区,我想找到n的k分区的排名。
  • 给定nk和一个等级,我想找到具有该等级的n的k分区。

我可以在不必计算感兴趣的分区之前的n的所有k分区的情况下执行此操作吗?

这个问题与其他问题不同,因为我们在这里讨论整数分区而不仅仅是组合。

bti*_*lly 6

这是 Python 中的一个解决方案,它依赖于两个想法。首先,动态编程来计算分区而不生成分区。其次,如果第一个值是,i那么我们可以将其视为一个盒子,上面有i * k一个分区。n-i*kk-1

partition_cache = {}
def distinct_partition_count (n, k):
    if n < k:
        return 0
    elif n < 1:
        return 0
    elif k < 1:
        return 0
    elif k == 1:
        return 1
    elif (n, k) not in partition_cache:
        answer = 0
        for i in range(1, n//k + 1):
            answer = answer + distinct_partition_count(n - i*k, k-1)
        partition_cache[(n, k)] = answer
    return partition_cache[(n, k)]

def rank_distinct_partition (values):
    values2 = sorted(values)
    n = sum(values)
    k = len(values)
    answer = 0
    highwater = 0
    for v in values:
        rise = v - highwater
        for i in range(1, rise):
            answer = answer + distinct_partition_count(n - k*i, k-1)
        highwater = v
        ## BUG HERE: was n = n - rise
        n = n - rise * k
        k = k - 1
    return answer

def find_ranked_distinct_partition (n, k, rank):
    if k == 1 and rank == 0:
        return [n]
    elif distinct_partition_count(n, k) <= rank:
        return None
    elif rank < 0:
        return None
    else:
        i = 1
        while distinct_partition_count(n - i*k, k-1) <= rank:
            rank = rank - distinct_partition_count(n - i*k, k-1);
            i = i + 1
        answer = find_ranked_distinct_partition(n - i*k, k-1, rank)
        return [i] + [j + i for j in answer]

print(rank_distinct_partition([2, 3]))
print(find_ranked_distinct_partition(5, 2, 1))
Run Code Online (Sandbox Code Playgroud)