zoukankan      html  css  js  c++  java
  • 有线电视网

    有线电视网

    题目大意:给出一棵树,叶子结点增加一定的权值,经过减少一定的权值,求在总权值(geq0)的情况下可以到达的叶子结点最多的数量.

    树上的背包问题

    这样来DP

    • 状态:(f[i][j])为以(i)为根的子树中,满足(j)个客户的需求所能获得的最大收益
    • 转移方程:(f[u][j] = max(f[u][j], f[u][j - k] + f[v][k] - e[i].val))

    在树上做背包,每搜到一个点就更新一遍,注意滚动数组,倒序

    代码

    #include <iostream>
    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    
    const int N = 3005;
    const int INF = 1147483640;
    
    struct Edge{
        int to, next, val;
    }e[N];
    
    int n, m, cnt;
    int son[N], head[N], money[N], f[N][N], sz[N];
    
    inline void addedge(int x, int y, int z){
        e[++cnt].to = y;
        e[cnt].val = z;
        e[cnt].next = head[x];
        head[x] = cnt;
        return;
    }
    
    int dfs(int x){
        if(x > n - m){
            f[x][1] = money[x];//如果是叶子结点,改变初始值
            return sz[x] = 1;
        }
        for(int i = head[x], v, l_sum = 0; i; i = e[i].next){
            v = e[i].to;
            l_sum = dfs(v);
            sz[x] += l_sum;
            for(int j = sz[x]; j; --j)//这个点包含的客户,每次都更新下
                for(int k = 1; k <= l_sum; ++k){//f[v][k]中的k限制于sz[v]
                    if(j - k < 0 ) break;
                    f[x][j] = std::max(f[x][j], f[x][j - k] + f[v][k] - e[i].val);
                }
        }
        return sz[x];
    }
    
    int main(){
        scanf("%d %d", &n, &m);
        for(int i = 1; i <= n - m; ++i){
            scanf("%d", &son[i]);
            for(int j = 1, x, y; j <= son[i]; ++j){
                scanf("%d %d", &x, &y);
                addedge(i, x, y); 
            }
        }
        for(int i = n - m + 1; i <= n; ++i)
            scanf("%d", &money[i]);
        for(int i = 1; i <= n; ++i){
            for(int j = 1; j <= m; ++j){
                f[i][j] = -INF;
            }
        }     
        dfs(1);
        for(int i = m; i; --i){
            if(f[1][i] >= 0){
                printf("%d", i);
                break;
            }
        }
        return 0;
    }
    

    错误qwq

    • 如果在有返回值的函数后面不加(return),而写其他东西,会很奇怪
    • (f[i][j])初始化为极小值后,转移的时候再减去边权会炸掉,变为正的,注意不要初始化太小了
  • 相关阅读:
    被忽视的调试工具Swagger
    MongoDB操作
    js获取当月第一天和最后一天
    vue中 关于$emit的用法
    map和flatmap的区别
    element 的el-dialog 浮层嵌套,第二次弹出的会被遮住
    el-table加背景色
    java 正则表达式匹配
    Python自动化测试 (七)logging 日志模块
    git安装配置与使用
  • 原文地址:https://www.cnblogs.com/LMSH7/p/9531917.html
Copyright © 2011-2022 走看看