树形背包两种写法的复杂度分析

大部分人的树形背包板子应该是写成下面这样的:

for(int i = head[u]; i; i = nxt[i]) {
    if(to[i] == fa)continue;
    dfs(to[i], u);
    sz[u] += sz[to[i]];
    for(int j = sz[u]; j >= 0; j--) {
        for(int k = 1; k <= min(j, sz[to[i]]); k++) {
            dp[u][j] = max(dp[u][j], dp[u][j - k] + dp[to[i]][k]);
        }
    }
}

然而,这种写法在链的情况下会被卡成 \(O(nm^2)\) 的。
可以像下面这样写,复杂度就是 \(O(nm)\)

for(int i = head[u]; i; i = nxt[i]) {
    if(to[i] == fa)continue;
    dfs(to[i], u);
    for(int j = sz[u]; j >= 0; j--) {
        for(int k = 1; k <= sz[to[i]]; k++) {
            dp[u][j + k] = max(dp[u][j + k], dp[u][j] + dp[to[i]][k]);
        }
    }
    sz[u] += sz[to[i]];
}
posted @ 2021-10-21 16:49  conprour  阅读(245)  评论(0编辑  收藏  举报