【JZOJ5661】药香沁鼻

Description
Description

Input
Input

Output
Output

Sample Input

6 9
1 1 1
1 1 100
8 1 1
1 3 6
2 3 1000
4 1 4

Sample Output

105

Hint
【样例解释】
其中一种最优解为:小 C?用 8 点能量摘下第 1,2,4,6 朵花,并放在药材中熬煮,由于第 4 朵花所钦慕的 3 号花不在药材中,所以第 4 朵花渐渐枯萎消失。最后剩下 3 朵花:1,2,6,药材所获得的最大贡献为 1+100+4=105。

Data Constraint
Data


Analysis

一眼看去是一个树形依赖背包问题,以前只会打 O ( n 3 ) (/捂脸)的
其实从根背包下去,把子节点的状态更新到本身,再走到下一个子节点即可,想想都是对的

#include<cstring>
#include<cstdio>
#define max(a,b) (a>b?a:b)
#define N 5001
#define P 10001

using namespace std;

int f[N][P],n,fir[N],nex[N],to[N],g[2][P],m,c[N],v[N];

void dg(int x){
    int y;
    for(int i=fir[x];i;i=nex[i]){
        y=to[i];
        for(int j=0;j<=m;j++)if(j<c[y] || f[x][j-c[y]]<0)f[y][j]=-1;else f[y][j]=f[x][j-c[y]]+v[y];
        dg(y);
        for(int j=0;j<=m;j++)if(f[y][j]>f[x][j])f[x][j]=f[y][j];
    }
}

int main(){
    scanf("%d %d",&n,&m);
    for(int i=1;i<=n;i++){
        int x;scanf("%d %d %d",&c[i],&x,&v[i]);
        if(i>1)to[i]=i,nex[i]=fir[x],fir[x]=i;
    }
    for(int i=0;i<=m;i++)f[1][i]=-1;if(c[1]<=m)f[1][c[1]]=v[1];
    dg(1);
    int ans=0;for(int i=0;i<=m;i++)ans=max(ans,f[1][i]);
    printf("%d",ans);
    return 0;
}

猜你喜欢

转载自blog.csdn.net/white_elephant/article/details/80424738