一直疑惑的问题:在树上的有父亲依赖的选点方案数如果有最多 m 个点的限制,用这样的代码复杂度是 O(nm2) :
void dfs(int u) {
dp[u][0] = 1, dp[u][1] = 1; //边界条件可能不对,不要在意
for (int v : tree[u]) {
dfs(v);
for (int i = m; i >= 0; i--) {
for (int j = 0; j <= i; j++) {
dp[u][i] = dp[v][j] * dp[u][j - i];
}
}
}
但如果限制一下枚举范围,用这样的代码:
siz[u] = 1;
for (int v : tree[u]) {
for (int i = 0; i <= siz[u]; i++) {
for (int j = 0; j <= siz[v] && i + j <= m; j++) {
(dp[i + j] += dp[u][i] * dp[v][j] % mod) %= mod;
}
}
siz[u] += siz[v];
siz[u] = min(siz[u], m);
}
时间复杂度变成了 O(nm)。
为什么?树形DP还有其他的优化吗?