• RNQOJ [stupid]愚蠢的矿工(树形依赖背包)


    题意

    题目链接

    Sol

    树形依赖背包板子题

    树形依赖背包大概就是说:对于一个点,只有选了它的父亲才能选自身

    把dfs序建出来,倒过来考虑

    (f[i][j])表示从第(i)个节点往后背包体积为(j)的最大价值

    转移的时候,只有选了该点才能从子树中转移而来

    (f[i][j] = max(f[i + 1][j - w[i]] + val[i], f[i + siz[rev[i]]][j]);)

    #include<bits/stdc++.h>
    using namespace std;
    const int MAXN = 3001, INF = 1e9 + 10;
    inline int read() {
        char c = getchar(); int x = 0, f = 1;
        while(c < '0' || c > '9') {if(c == '-')f =- 1; c = getchar();}
        while(c >= '0' && c <= '9') x = x * 10 + c - '0', c = getchar();
    	return x * f;
    }
    int N, M, w[MAXN], val[MAXN], siz[MAXN], rev[MAXN], f[MAXN][MAXN], tot = 0;
    vector<int> v[MAXN];
    void dfs(int x, int _fa) {
    	rev[++tot] = x; siz[x] = 1;
    	for(int i = 0, to; i < v[x].size(); i++) {
    		if((to = v[x][i]) == _fa) continue;
    		dfs(to, x);
    		siz[x] += siz[to];
    	}
    }
    main() {
    	N = read(); M = read();
    	for(int i = 1; i <= N; i++) val[i] = read(), w[i] = 1;
    	for(int i = 1; i <= N; i++) {
    		int x = read(), y = read();
    		if(x == 0) continue;
    		v[x].push_back(y); v[y].push_back(x);
    	}
    	dfs(1, 0);
    	for(int i = N; i >= 1; i--) {
    		for(int j = 0; j <= M; j++) {
    			f[i][j] = f[i + siz[rev[i]]][j];
    			if(j >= w[i]) f[i][j] = max(f[i][j], f[i + 1][j - w[rev[i]]] + val[rev[i]]);
    		//	printf("%d %d %d
    ", i, j, f[i][j]);
    		}
    	}
    	cout << f[1][M];
    }
    /*
    */	
    
    
  • 相关阅读:
    alpine下ruby安装sass compass报 Error installing compass 错误的解决方案
    Andoid项目中增加openCV的依赖
    appium教程_4.adb常用命令
    appium教程_2.概念加深
    appium教程_1.基础概念认知
    windows下查看进程(进阶)
    linux下安装google-chrome浏览器和chromedriver
    钉钉内网穿透windows启动命令
    Docker
    HTTP协议
  • 原文地址:https://www.cnblogs.com/zwfymqz/p/9741035.html
Copyright © 2020-2023  润新知