码迷,mamicode.com
首页 > 其他好文 > 详细

有线电视网

时间:2018-08-24 21:18:35      阅读:133      评论:0      收藏:0      [点我收藏+]

标签:print   代码   ring   class   mat   背包问题   cst   滚动数组   sum   

有线电视网

题目大意:给出一棵树,叶子结点增加一定的权值,经过减少一定的权值,求在总权值\(\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]\)初始化为极小值后,转移的时候再减去边权会炸掉,变为正的,注意不要初始化太小了

有线电视网

标签:print   代码   ring   class   mat   背包问题   cst   滚动数组   sum   

原文地址:https://www.cnblogs.com/LMSH7/p/9531917.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!