HDU 1011(树形)

题意:

就是一个房间有a个虫子,有b个“大脑”(百度翻译的,将就看吧。。。)你把虫子杀了就可以获得b个大脑。一个士兵能杀死20个虫子。

思路:

猛的一看,这不就是背包吗?但是好像又是树有关系。那就建树啊,在树上dp一下就行了!
建树按照这个建树,感觉比较方便。

struct node{
    int v,next;
}edge[10010];
int head[110],cur;
void add(int s,int t){
    edge[cur].v=t;
    edge[cur].next=head[s];
    head[s]=cur++;
}

建好树之后背包一遍就可以了。

#include<bits/stdc++.h>
using namespace std;
struct node{
    int v,next;
}edge[10010];
int head[110],cur;
int dp[110][110];
int n,m,a,b;
void add(int s,int t){
    edge[cur].v=t;
    edge[cur].next=head[s];
    head[s]=cur++;
}
int num[110],v[110];
void dfs(int son,int father){
    int tmp=(num[son]+19)/20;
    for(int i=head[son];~i;i=edge[i].next){
        int to=edge[i].v;
        if(to==father)continue;
        dfs(to,son);
        for(int j=m;j>=tmp;j--){
            for(int k=1;j-k>=tmp&&k<=m;k++){
                dp[son][j]=max(dp[son][j],dp[son][j-k]+dp[to][k]);
            }
        }
    }
    for(int i=tmp;i<=m;i++)dp[son][i]+=v[son];
}
int main(){
    while(~scanf("%d%d",&n,&m)&&(~n||~m)){
        memset(head,-1,sizeof head),memset(dp,0,sizeof dp),cur=0;
        for(int i=1;i<=n;i++)scanf("%d%d",&num[i],&v[i]);
        for(int i=1;i<n;i++){
            scanf("%d%d",&a,&b);
            add(a,b),add(b,a);
        }
        if(m==0){puts("0");continue;}
        dfs(1,0);
        printf("%d\n",dp[1][m]);
    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/qq_41635132/article/details/82750071