zoukankan      html  css  js  c++  java
  • icpc2020南京站 M.Monster Hunter (树形背包)

    题目链接:https://ac.nowcoder.com/acm/problem/216013

    (dp[i][j][0/1]) 表示杀到第 (i) 个节点,已经用魔法杀了 (j) 个怪物,当前节点使不使用魔法,所消耗的最小能量

    注意下树形背包的写法

    #include<iostream>
    #include<algorithm>
    #include<cstring>
    #include<cstdio>
    #include<cmath>
    using namespace std;
    typedef long long ll;
    
    const int maxn = 2010; 
    const ll inf = 1ll << 60ll;
    
    int T, n, m;
    int a[maxn];
    ll tmp[maxn][2], dp[maxn][maxn][2];
    
    int h[maxn], cnt = 0;
    struct E{
    	int to, next;
    }e[maxn << 1];
    void add(int v, int u){
    	e[++cnt].next = h[u];
    	e[cnt].to = v;
    	h[u] = cnt;
    }
    
    int sz[maxn];
    
    void dfs(int u, int par){
    	sz[u] = 1;
    	dp[u][0][0] = a[u];
    	dp[u][1][1] = 0;
    	for(int i = h[u] ; i != -1 ; i = e[i].next){
    		int v = e[i].to;
    		if(v == par) continue;
    		
    		dfs(v, u);
    		
    		for(int j = 0 ; j <= sz[u] + sz[v] ; ++j) tmp[j][0] = tmp[j][1] = inf;
    		for(int j = 0 ; j <= sz[u] ; ++j){
    			for(int k = 0 ; k <= sz[v] ; ++k){
    				tmp[j + k][0] = min(tmp[j + k][0], dp[u][j][0] + dp[v][k][0] + a[v]);
                    tmp[j + k][0] = min(tmp[j + k][0], dp[u][j][0] + dp[v][k][1]);
                    tmp[j + k][1] = min(tmp[j + k][1], dp[u][j][1] + dp[v][k][0]);
                    tmp[j + k][1] = min(tmp[j + k][1], dp[u][j][1] + dp[v][k][1]);
    			}
    		}
    		
    		for(int j = 0 ; j <= sz[u] + sz[v] ; ++j){
    			dp[u][j][1] = tmp[j][1];
    			dp[u][j][0] = tmp[j][0];
    		}
    		
    		sz[u] += sz[v];
    	}
    }
    
    ll read(){ ll s = 0, f = 1; char ch = getchar(); while(ch < '0' || ch > '9'){ if(ch == '-') f = -1; ch = getchar(); } while(ch >= '0' && ch <= '9'){ s = s * 10 + ch - '0'; ch = getchar(); } return s * f; }
    
    int main(){
    	T = read();
    	
    	while(T--){
    		memset(h, -1, sizeof(h));
    		n = read();	
    		
    		for(int i = 0 ; i <= n ; ++i){
    			for(int j = 0 ; j <= n ; ++j){
    				dp[i][j][0] = dp[i][j][1] = inf;
    			} 
    		} 
    
    		cnt = 0;
    		
    		int x;
    		for(int i = 2 ; i <= n ; ++i){
    			x = read();
    			add(i, x), add(x, i);
    		}
    		for(int i = 1 ; i <= n ; ++i) a[i] = read();
    		
    		dfs(1, 0);
    		
    		for(int i = 0 ; i <= n ; ++i) printf("%lld ", min(dp[1][i][0], dp[1][i][1]));
    		printf("
    ");
    	}
    
    	return 0;
    }
    
  • 相关阅读:
    qt creator源码全方面分析(2-10-4)
    qt creator源码全方面分析(2-10-3)
    qt creator源码全方面分析(2-10-2)
    qt creator源码全方面分析(2-10-1)
    qt creator源码全方面分析(2-9)
    flex布局使用
    filter,map,reduce三个数组高阶函数的使用
    git的使用总结
    axios学习和使用
    vuex的学习
  • 原文地址:https://www.cnblogs.com/tuchen/p/14194799.html
Copyright © 2011-2022 走看看