来自AI:
dp[i][j]
表示以节点i
为根的子树,当节点i
的权值为j
时的方案数。i
,dp[i][j]=1
,因为叶子节点的权值可以是1
到V
中的任意一个值。i
,它的权值j
要满足j >= w_{fa_i}
,并且它的子节点的权值要满足相应的条件。所以dp[i][j]=\prod_{k\in children(i)} \sum_{l = j}^{V}dp[k][l]
,其中children(i)
表示节点i
的子节点集合。O(nV)
,因为对于每个节点都要考虑V
种权值情况。i
,计算sum[i][j]=\sum_{l = j}^{V}dp[i][l]
。dp[i][j]
时,可以使用dp[i][j]=\prod_{k\in children(i)} sum[k][j]
。sum[i][j]
时,可以使用sum[i][j]=sum[i][j + 1]+dp[i][j]
。dp[i][j]
和sum[i][j]
的时间复杂度都可以降低到O(n)
,因为对于每个节点只需要O(1)
的时间来更新dp
和sum
数组。O(nV)
优化到了O(n)
。以下是使用Python实现的代码示例:
n, V = map(int, input().split())
adj_list = [[] for _ in range(n + 1)]
for _ in range(n - 1):
u, v = map(int, input().split())
adj_list[u].append(v)
adj_list[v].append(u)
dp = [[0] * (V + 1) for _ in range(n + 1)]
sum_dp = [[0] * (V + 1) for _ in range(n + 1)]
mod = 10**9 + 7
def dfs(node, parent):
for child in adj_list[node]:
if child!= parent:
dfs(child, node)
if len(adj_list[node]) == 1 and node!= 1: # 叶子节点
for j in range(1, V + 1):
dp[node][j] = 1
else:
for j in range(1, V + 1):
product = 1
for child in adj_list[node]:
if child!= parent:
product = (product * sum_dp[child][j]) % mod
dp[node][j] = product
for j in range(V, 0, -1):
sum_dp[node][j] = (sum_dp[node][j + 1] + dp[node][j]) % mod
dfs(1, -1)
print(sum(dp[1]) % mod)
在上述代码中,首先构建了树的邻接表adj_list
,然后使用深度优先搜索dfs
来计算dp
和sum_dp
数组,最后输出以根节点为1
的满足条件的赋权值方案数对10**9 + 7
取模的结果。
这不是 O(n) 吧