zoukankan      html  css  js  c++  java
  • 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;
            }
    }
    
  • 相关阅读:
    微信 播放视频
    json与页面动态绑定
    layer mobile开发layer.full
    Layer 使用
    分享一段,图片加水印的代码。本人修改过多次
    jenkins .net linux
    Jenkins .net windows
    《微服务-架构与实践》
    分布式网站架构
    Go 并发随机打印1-n
  • 原文地址:https://www.cnblogs.com/hznumqf/p/13871407.html
Copyright © 2011-2022 走看看