• Jzoj5661 药香沁鼻


    有依赖关系的树形背包,算是又积累了一种做法

    一个经典的做法就是设f[x][j]表示在x子树内,容量为j的最大获利

    那么转移可以写成 f[x][j]=max{f[x][j],f[x][j-k]+f[v][k]} v是x的子树

    我们在dp时记录背包的剩余空间,就可以得到80分

    一个更好的优化就是用dfs序,复杂度直接下降为O(nm)

    当然最快的做法还是直接在树上做,我们还是设f[x][j]表示x节点子树取到最大的答案

    那么f[x][j]=max(f[x][j],f[x][j-w[y]]+v[u]) 发现转移非常快,加上记录背包的剩余空间,可以非常快的通过

    #pragma GCC optimize("O3")
    #pragma G++ optimize("O3")
    #include<stdio.h>
    #include<string.h>
    #include<algorithm>
    #define N 5010
    using namespace std;
    struct edge{ int v,nt; } G[N];
    int n,m,cnt,h[N],f[N][10010],v[N],w[N];
    inline void gmax(int& x,int y){ x<y?x=y:0; }
    inline void adj(int x,int y){
    	G[++cnt]=(edge){y,h[x]}; h[x]=cnt;
    }
    inline void dfs(int x,int m){
    	for(int y,i=h[x];i;i=G[i].nt){
    		y=G[i].v;
    		if(m<w[y]) continue;
    		memcpy(f[y],f[x],m-w[y]+1<<2);
    		dfs(y,m-w[y]); 
    		for(int j=m;j>=w[y];--j)
    			gmax(f[x][j],f[y][j-w[y]]+v[y]);
    	}
    }
    int main(){
    	freopen("medicine.in","r",stdin);
    	freopen("medicine.out","w",stdout);
    	scanf("%d%d",&n,&m);
    	for(int x,i=1;i<=n;++i){
    		scanf("%d%d%d",w+i,&x,v+i);
    		if(x!=i) adj(x,i);
    	}
    	dfs(1,m-w[1]);
    	for(int j=m-w[1];j;--j) **f=max(**f,f[1][j]);
    	printf("%d
    ",**f+v[1]);
    }

  • 相关阅读:
    深入理解JVM内幕:从基本结构到Java 7新特性
    通过Java反射做实体查询
    Hadoop教程(一)
    很不错的js特效
    java utf8字符 导出csv 文件的乱码问题。
    spring MVC使用Interceptor做用户登录判断
    Bootstrap--全局css样式之图片
    Bootstrap-全局css样式之按钮
    Bootstrap--全局css样式之表单
    Bootstarp--全局CSS样式之表格
  • 原文地址:https://www.cnblogs.com/Extended-Ash/p/9477106.html
Copyright © 2020-2023  润新知