我有这个任务:

安娜妈妈打开了一包糖果,她想把糖果分发给她的子元素们作为奖励.从而使得它们不 他们之间的冲突,所以当然谁完成了一个更好的地方在竞争中不能少, 比在更糟糕的地方吃的更好安娜可以用多少种方法把C个糖果分给D个子元素?

任务:
对于给定的数字D和C,找出糖果的可能分布的数量.

入口:
在文件的第一行有一个数字Q,表示集合的数量. 有Q行,有一对数字D和C.

  • 1个≤Q≤1000
  • 1个≤D≤100
  • 1个≤C≤5,000

输出:
程序的输出是每组模(2^30)-1在单独的行上的结果.

例如 输入:

3
1 10
2 4
3 8

输出:

1
3
10

我做了这个代码,它工作,但当我有1000个输入,我得到** Timelimit **在判断器,你能帮助我做代码,将工作得更快吗?

def generate_combinations(d, c, current_combination=None, combinations=None):
    if current_combination is None:
        current_combination = []

    if combinations is None:
        combinations = []

    if d == 0:
        if c == 0:
            if all(current_combination[i] <= current_combination[i + 1] for i in range(len(current_combination) - 1)):
                
                combinations.append(list(current_combination))
        return

    for i in range(c + 1):
        generate_combinations(d - 1, c - i, current_combination + [i], combinations)

    return combinations

c = 8  
d = 3 

pocet = int(input())
for i in range(pocet):
    d, c = map(int, input().split())
    print(len(generate_combinations(d, c)))

我也有使用动态编程的版本

def dynamic_programming(d, c):
    dp = [[0] * (c + 1) for _ in range(d + 1)]
    dp[0][0] = 1

    for i in range(1, d + 1):
        for j in range(c + 1):
            dp[i][j] = dp[i - 1][j]
            if j >= i:
                dp[i][j] += dp[i][j - i]
            dp[i][j] %= (2 ** 30 - 1)
    b = dp[d][c]
    return dp[d][c]

q = int(input().strip())

for i in range(q):
    d, c = map(int, input().split())
    print(dynamic_programming(d, c))

为了更好地理解,这里是一个例子,如果我们想把8个糖果分给3个子元素,我们有21种可能性:

[0, 0, 8]
[0, 1, 7]
[0, 2, 6]
[0, 3, 5]
[0, 4, 4]
[0, 5, 3]
[0, 6, 2]
[0, 7, 1]
[0, 8, 0]
[1, 0, 7]
[1, 1, 6]
[1, 2, 5]
[1, 3, 4]
[1, 4, 3]
[1, 5, 2]
[1, 6, 1]
[1, 7, 0]
[2, 0, 6]
[2, 1, 5]
[2, 2, 4]
[2, 3, 3]
[2, 4, 2]
[2, 5, 1]
[2, 6, 0]
[3, 0, 5]
[3, 1, 4]
[3, 2, 3]
[3, 3, 2]
[3, 4, 1]
[3, 5, 0]
[4, 0, 4]
[4, 1, 3]
[4, 2, 2]
[4, 3, 1]
[4, 4, 0]
[5, 0, 3]
[5, 1, 2]
[5, 2, 1]
[5, 3, 0]
[6, 0, 2]
[6, 1, 1]
[6, 2, 0]
[7, 0, 1]
[7, 1, 0]
[8, 0, 0]

只有10种可能性适合这项任务:

[0, 0, 8]
[0, 1, 7]
[0, 2, 6]
[0, 3, 5]
[0, 4, 4]
[1, 1, 6]
[1, 2, 5]
[1, 3, 4]
[2, 2, 4]
[2, 3, 3]

推荐答案

考虑到每个糖果分配是n个糖果的integer partition分,分成k个部分.还应注意,对于n个糖果的每个分区,存在对子有效的单个唯一分配糖果(例如,对于n=7,分区3 3 1只能以一种方式映射到子[0, 3, 3],其他任何东西都将无效).

这样,我们只需要计算n个k分区的数量,它有一个很好的递归公式:

p(0, 0) = 1
p(n, k) = 0  if n <= 0 or k <= 0
p(n, k) = p(n - k, k) + p(n - 1, k - 1)

现在,我们需要小心—这个公式计算非空分区,但我们允许给子元素0个糖果.我们可以改变递归关系,但有一个更简单的方法;如果我们在开始时 for each 子元素添加1个额外的糖果,然后想象我们只是从他们的部分中删除一个糖果,这就像我们允许空分区一样.

在Python中实现:

from functools import cache

@cache
def count_parts(candies, children):
    if candies == children == 0:
        return 1
    if candies <= 0 or children <= 0:
        return 0
    return count_parts(candies - children, children) + count_parts(candies - 1, children - 1)

用法示例:

test_cases = [(10, 1), (4, 2), (8, 3)]
for candies, children in test_cases:
    print(count_parts(candies + children, children))

输出:

1
3
10

这将是O(C*D)个时间和空间,自下而上的动态编程解决方案将具有相同的时间复杂度,但在实践中会稍微快一些,并且可以使其具有线性(以C为单位)的空间复杂度.

细节是逃避我目前,但我相信也有一个早期退出捷径计算p(2*k, k),可以用于进一步的加速以及.

Python相关问答推荐

根据条件将新值添加到下面的行或下面新创建的行中

加速Python循环

对象的`__call__`方法的setattr在Python中不起作用'

当我try 在django中更新模型时,模型表单数据不可见

Python Pandas获取层次路径直到顶层管理

判断solve_ivp中的事件

如何在Python中使用Pandas将R s Tukey s HSD表转换为相关矩阵''

手动设置seborn/matplotlib散点图连续变量图例中显示的值

PYTHON、VLC、RTSP.屏幕截图不起作用

Flask运行时无法在Python中打印到控制台

如果包含特定值,则筛选Groupby

pandas fill和bfill基于另一列中的条件

为用户输入的整数查找根/幂整数对的Python练习

Python将一个列值分割成多个列,并保持其余列相同

提取最内层嵌套链接

Scipy差分进化:如何传递矩阵作为参数进行优化?

如何在PYTHON中向单元测试S Side_Effect发送额外参数?

解析CSV文件以将详细信息添加到XML文件

如何在Polars中将列表中的新列添加到现有的数据帧中?

#将多条一维曲线计算成其二维数组(图像)表示