Arrays k部分整数划分的秩与反秩

Arrays k部分整数划分的秩与反秩,arrays,algorithm,combinations,ranking,integer-partition,Arrays,Algorithm,Combinations,Ranking,Integer Partition,对于正整数n和k,设“n的k-划分”是k个不同的正整数的排序列表,这些正整数加起来等于n,且给定的n的k-划分的“秩”是其在所有这些列表的排序列表中的位置(从0开始) 例如,有两个5的2分区(n=5,k=2):[1,4]和[2,3]。由于[1,4]在词典顺序中位于[2,3]之前,[1,4]的秩为0,[2,3]的秩为1 所以,我想做两件事: 给定n,k和n的k-划分,我想求n的k-划分的秩 给定n,k和一个秩,我想找到n的k-划分 我能做到这一点,而不必计算n的所有k-划分,它们位于感兴趣的k

对于正整数n和k,设“n的k-划分”是k个不同的正整数的排序列表,这些正整数加起来等于n,且给定的n的k-划分的“秩”是其在所有这些列表的排序列表中的位置(从0开始)

例如,有两个5的2分区(n=5,k=2):[1,4]和[2,3]。由于[1,4]在词典顺序中位于[2,3]之前,[1,4]的秩为0,[2,3]的秩为1

所以,我想做两件事:

  • 给定n,k和n的k-划分,我想求n的k-划分的秩
  • 给定n,k和一个秩,我想找到n的k-划分
我能做到这一点,而不必计算n的所有k-划分,它们位于感兴趣的k-划分之前吗


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

这里有一个Python解决方案,它依赖于两个思想。首先,动态规划可以在不生成分区的情况下对分区进行计数。其次,如果第一个值是
i
,那么我们可以将其视为一个
i*k
框,该框将
n-i*k
划分为
k-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))
partition_cache={}
def不同分区计数(n,k):
如果nelif distinct_partition_count(n,k)这里有一个Python解决方案,它依赖于两个思想。首先,动态规划可以在不生成分区的情况下对分区进行计数。其次,如果第一个值是
i
,那么我们可以将其视为一个
i*k
框,该框将
n-i*k
划分为
k-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))
partition_cache={}
def不同分区计数(n,k):
如果nelif distinct_partition_count(n,k)你在这个问题上做过自己的工作吗?我认为它可以通过递归和二维数组来完成。但我不知道该怎么做-(可能重复@Yonlif我认为它不是重复的,而是非常相似的想法解决方案。你在这个问题上做过自己的工作吗?我认为它可以通过递归和二维数组来完成。但我没有弄清楚,它是如何做到的。)-(可能重复的@Yonlif我认为它不是重复的,而是非常相似的想法解决方案。对于
n=101,k=10,rank=129905
,用
2,3,5,7,9,10,13,15,18,19
@TThoEinthausend构建的
n=101,k=10
不起作用。我已经验证了这个bug。我正在试图找出错误所在。但是对于
n=101,k=10
它首先发生在
上>rank=24
@TThoEinthausend很抱歉花了我这么长时间。错误已经修复。我在代码中标记了错误的位置。对
n=101,k=10,rank=129905
无效,它是由
2,3,5,7,9,10,13,15,18,19
@TThoEinthausend构建的。我已经验证了错误。我正在试图找出错误所在。但是对于
n=101,k=10
它首先发生在
rank=24
@TThoEinthausend上。很抱歉,我花了这么长时间。错误已经修复。我在代码中标记了错误所在的位置。