只需在此处添加我的方法以及其他方法即可。它是用 Python 编写的,所以它实际上就像伪代码。
我的第一种方法奏效了,但效率极低:
def intPart(buckets, balls):
return uniqify(_intPart(buckets, balls))
def _intPart(buckets, balls):
solutions = []
# base case
if buckets == 1:
return [[balls]]
# recursive strategy
for i in range(balls + 1):
for sol in _intPart(buckets - 1, balls - i):
cur = [i]
cur.extend(sol)
solutions.append(cur)
return solutions
def uniqify(seq):
seen = set()
sort = [list(reversed(sorted(elem))) for elem in seq]
return [elem for elem in sort if str(elem) not in seen and not seen.add(str(elem))]
这是我重新设计的解决方案。它完全避免了通过使用 max_ 变量跟踪前一个桶中的球来“唯一化”它的需要。这会对列表进行排序并防止任何欺骗:
def intPart(buckets, balls, max_ = None):
# init vars
sols = []
if max_ is None:
max_ = balls
min_ = max(0, balls - max_)
# assert stuff
assert buckets >= 1
assert balls >= 0
# base cases
if (buckets == 1):
if balls <= max_:
sols.append([balls])
elif balls == 0:
sol = [0] * buckets
sols.append(sol)
# recursive strategy
else:
for there in range(min_, balls + 1):
here = balls - there
ways = intPart(buckets - 1, there, here)
for way in ways:
sol = [here]
sol.extend(way)
sols.append(sol)
return sols
只是为了全面起见,这是从 用 Perl 编写的MJD偷来的另一个答案:
#!/usr/bin/perl
sub part {
my ($n, $b, $min) = @_;
$min = 0 unless defined $min;
# base case
if ($b == 0) {
if ($n == 0) { return ([]) }
else { return () }
}
my @partitions;
for my $first ($min .. $n) {
my @sub_partitions = part($n - $first, $b-1, $first);
for my $sp (@sub_partitions) {
push @partitions, [$first, @$sp];
}
}
return @partitions;
}