Hdu1011 树形dp,多重背包

坑点:可能我英语不太好没看出来,假如一个点bugs为0,也至少需要有一个人通过他(不用停留在上面,也就是在后面可以再使用),所以只需要在bugs为0可以直接获得brain的基础上,把所有的dp[u][0]都初始化为0就可以了。

#include <cstdio>
#include <vector>
#include <cstring>
#include <algorithm>
using namespace std;

const int N=1e2+5;
int n,m;
int bugs[N], p[N];
int dp[N][N];
int t[N];
vector<int> G[N];

void init() {
    for(int i=1; i<=n; ++i) {
        G[i].clear();
    }
}

void AddEdge(int a, int b) {
    G[a].push_back(b);
    G[b].push_back(a);
}

void solve(int u, int fa) {
    for(int i=0; i<G[u].size(); ++i) {
        int v=G[u][i];
        if(v!=fa) {
            solve(v, u);
        }
    }
    memset(t, 0, sizeof(t));
    for(int i=0; i<G[u].size(); ++i) {
        int v=G[u][i];
        if(v==fa) continue;
        for(int j=m; j>=0; --j) {
            for(int k=0; k<=j; ++k)
            {
                t[j]=max(t[j], t[j-k]+dp[v][k]);
            }
        }
    }
    for(int i=1; i<=m; ++i) {
        int r=bugs[u]?i-(bugs[u]-1)/20-1:i;
        if(r<0)
        {
            dp[u][i]=0;
            continue;
        }
        dp[u][i]=p[u]+t[r];
    }
}

int main() {
    while(~scanf("%d%d", &n, &m)) {
        if(n==-1&&m==-1) break;
        init();
        for(int i=1; i<=n; ++i) {
            scanf("%d%d", bugs+i, p+i);
        }
        for(int i=1; i<n; ++i) {
            int a, b;
            scanf("%d%d", &a, &b);
            AddEdge(a, b);
        }
        solve(1, 0);
        printf("%d\n", dp[1][m]);
    }
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值