选课

我觉得我好像已经理解树形背包了。


 套路化的树形背包。

递推公式长这样:f[i][j]=max(f[i][j],f[i][j-k]+f[t][k]);

注意f[i][0]应该在最后附为0,不然就相当于是取前m大了。

看代码:

#include<bits/stdc++.h>
using namespace std;
const int maxn=500;
int n,m,f[maxn][maxn],val[maxn];
int beg[maxn<<1],nex[maxn<<1],to[maxn<<1],e;
inline void add(int x,int y){
    e++;nex[e]=beg[x];
    beg[x]=e;to[e]=y;
}
int sz[maxn];
inline void dfs(int x,int fa){
    f[x][1]=val[x];
    //f[x][0]=0;
    for(int i=beg[x];i;i=nex[i])
        if(to[i]!=fa)dfs(to[i],x);
    for(int i=beg[x];i;i=nex[i])
        if(to[i]!=fa)
        for(int j=m+1;j>=0;j--)
            for(int k=0;k<=j;k++)
        f[x][j]=max(f[x][j],f[x][j-k]+f[to[i]][k]);
    f[x][0]=0;
}
int main(){
    cin>>n>>m;
    int x,rt;
    for(int i=1;i<=n;i++){
        scanf("%d%d",&x,&val[i]);
        add(x,i);
    }
    memset(f,-0x3f,sizeof(f));
    dfs(0,0);
    printf("%d\n",f[0][m+1]);
    return 0;
}

深深地感到自己的弱小。

 

posted @ 2020-03-11 11:49  syzf2222  阅读(120)  评论(0编辑  收藏  举报