制定dp问题[Codeforces 414 B]

问题描述

所有这些都是来自代码力竞赛的problem statement

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的良好序列的数量,其序列以j th 号结尾,而过渡表为以下伪代码

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]

但是据我了解,我们需要两个西格玛,一个用于除数,另一个用于长度。请帮助我纠正我的理解。

我的代码->

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)

链接到问题:https://codeforces.com/problemset/problem/414/B

解决方法

因此,我们将dp [i] [j]定义为长度为恰好 i且以最后一个元素j为结尾的良好序列的数量。

现在,对于所有x s.t,dp [i] [j] = Sum(dp [i-1] [x])。 x是i的除数。请注意,x可以等于j本身。

这是正确的,因为如果已经发现长度为i-1的某个序列以某个值x结尾,那么我们可以简单地将j添加到它的末端并形成一个满足所有条件的新序列。 / p>

我想你的困惑在于长度。事实是,由于我们当前的长度为i,因此只有在其长度为i-1时,我们才能将j添加到序列的末尾,因此我们无法迭代其他长度。

希望这很清楚。