• 洛谷P2015 二叉苹果树


    题意:

    数有(N)个节点,根编号为(1),一根树枝连接两个编号,树枝上有一定数量的苹果,给定需要保留的边数,求最多能留住多少苹果。

    思路:

    树形(DP) + 有依赖的背包问题
    看成有依赖的背包问题:f[u][j]就表示以(u)为根节点的子树,选(j)条边的最大价值。
    那么转移方程:(f[u][j] = max(f[u][j], f[u][j - 1 - k] + f[son][k] + w[i]))
    为什么有一个(f[u][j - 1 - k])而不是(f[u][j - k])呢,因为在(u)(son)之间本来就有一条边,所以需要减去。

    #include <bits/stdc++.h>
    
    using namespace std;
    
    const int N = 110, M = N * 2;
    int h[N], e[M], ne[M], w[M], idx;
    int n, m;
    int f[N][N];
    
    void add(int a, int b, int c) {
        e[idx] = b, w[idx] = c, ne[idx] = h[a], h[a] = idx++;
    }
    
    void dfs(int u, int father) {
        for (int i = h[u]; ~i; i = ne[i]) {
            int son = e[i];
            if (son == father) continue;
            dfs(son, u);
            for (int j = m; j >= 0; j--) {
                for (int k = 0; k <= j - 1; k++) {
                    f[u][j] = max(f[u][j], f[u][j - 1 - k] + f[son][k] + w[i]);
                }
            }
        }
    }
    
    int main() {
        cin >> n >> m;
        memset(h, -1, sizeof h);
        for (int i = 1; i <= n - 1; i++) {
            int a, b, c;
            cin >> a >> b >> c;
            add(a, b, c), add(b, a, c);
        }
        
        dfs(1, -1);
        
        cout << f[1][m] << endl;
        
        return 0;
    }
    
  • 相关阅读:
    [luogu3334]抛硬币
    [luogu3706]硬币游戏
    [luogu4548]歌唱王国
    [hdu4652]Dice
    [atAGC013F]Two Faced Cards
    [atAGC045F]Division into Multiples
    [atAGC045E]Fragile Balls
    [atAGC045D]Lamps and Buttons
    [luogu5574]任务分配问题
    [luogu4331]数字序列
  • 原文地址:https://www.cnblogs.com/ZhengLijie/p/15103931.html
Copyright © 2020-2023  润新知