【发布时间】:2020-08-11 09:39:27
【问题描述】:
这里都是 problem statement 来自 codeforces 的旧竞赛
l个整数序列b 1, b 2, ..., b l (1 ≤ b 1 ≤ b 2 ≤ ... ≤ b 如果每个数除以(没有余数),则 l ≤ n) 称为好数 序列中的下一个数字。更正式地为所有我 (1 ≤ i ≤ l - 1)。
给定 n 和 k 找到长度为 k 的好序列的数量。作为 答案可以是相当大的打印它模 1000000007 (109 + 7)。
我已将我的dp[i][j] 公式化为长度为i 的好的序列数,以jth 数结尾,转换表为以下伪代码
dp[k][n] =
for each factor of n as i do
for j from 1 to k - 1
dp[k][n] += dp[j][i]
end
end
但在社论中是这样给出的
Lets define dp[i][j] as number of good sequences of length i that ends in j.
Let's denote divisors of j by x1, x2, ..., xl. Then dp[i][j] = sigma dp[i - 1][xr]
但在我的理解中,我们需要两个 sigma,一个用于除数,另一个用于长度。请帮助我纠正我的理解。
我的代码 ->
MOD = 10 ** 9 + 7
N, K = map(int, input().split())
dp = [[0 for _ in range(N + 1)] for _ in range(K + 1)]
for k in range(1, K + 1):
for n in range(1, N + 1):
c = 1
for i in range(1, n):
if n % i != 0:
continue
for j in range(1, k):
c += dp[j][i]
dp[k][n] = c
c = 0
for i in range(1, N + 1):
c = (c + dp[K][i]) % MOD
print(c)
【问题讨论】:
-
为什么需要两次求和?如果考虑
a_i的所有可能除数,那么您知道a_i之前的序列(以所选除数结尾)的长度必须恰好为(i - 1)。 (请注意,问题询问长度确切k的序列)
标签: algorithm dynamic-programming