• P1273 有线电视网 树形DP 树上背包


    P1273 有线电视网 树形DP 树上背包

    题意

    给定一颗有根树,要求选择最多的叶子结点,并且使得达到这些叶子结点的花费(可以理解成到叶子的路径权值和) 小于等于选择的叶子结点的点权和。

    [2leq nleq 3000\ 1leq m leq n - 1 ]

    分析

    经典的树上背包问题。

    可以对一些叶子结点进行选或者不选的决策

    以下参考洛谷 yqw2486的题解

    状态转移方程

    [dp[i][u][j] = max(dp[i - 1][u][j - k] + dp[v的总儿子数][v][k] - w(u,v)) ]

    (dp[i][u][j])表示以(u)为根的子树的前(i)棵子树中选择(j)个节点能够获得的最大费用

    边界

    [dp[u][1] = w[u]\ dp[u][0] = 0 ]

    显然我们可以类似01背包的办法滚动一维

    [dp[u][j] = max(dp[u][j-k] + dp[v][k] - w(u,v)) ]

    代码

    struct Edge {
        int v;
        int w;
        Edge(int _v, int _w) {
            v = _v;
            w = _w;
        }
    };
    
    vector<Edge> e[3005];
    int w[3005];
    int dp[3005][3005];
    int n, m;
    
    int dfs(int u) {
        if (u > n - m) {
            dp[u][1] = w[u];
            dp[u][0] = 0;
            return 1;
        }
        dp[u][0] = 0;
        int siz = 0;
        for (auto v : e[u]) {
            int val = v.w;
            int vv = v.v;
            int t = dfs(vv);
            siz += t;
            for(int j = siz;j > 0;j--)
                for (int k = 0; k <= min(j, t); k++) 
                    dp[u][j] = max(dp[u][j], dp[u][j - k] + dp[vv][k] - val);
                
        }
        return siz;
    }
    
    int main() {
        n = readint();
        m = readint();
        for (int i = 1; i <= n - m; i++) {
            int k = readint();
            for (int j = 1; j <= k; j++) {
                int x = readint();
                int y = readint();
                e[i].push_back(Edge(x, y));
            }
        }
        for (int i = n - m + 1; i <= n; i++)
            w[i] = readint();
        for (int i = 0; i < 3005; i++)
            for (int j = 0; j < 3005; j++)
                dp[i][j] = -1e9;
        for (int i = 0; i < 3005; i++)
            dp[0][i] = 0;
        dfs(1);
        for (int i = m; i >= 0; i--)
            if (dp[1][i] >= 0) {
                printf("%d", i);
                break;
            }
    }
    
  • 相关阅读:
    signals系列之一——基本用法
    libevent系列之一——libevent介绍
    memcached完全剖析系列——一、memcached基础
    分布式算法一——一致性hash算法
    spring容器启动过程
    dubbo源码之四——服务发布二
    dubbo源码之四——dubbo服务发布
    dubbo源码之三——dubbo重构
    dubbo源码之三-模块依赖
    [模板](luogu P3387)縮點
  • 原文地址:https://www.cnblogs.com/hznumqf/p/13871407.html
Copyright © 2020-2023  润新知