zoukankan      html  css  js  c++  java
  • 2020(ICPC)亚洲区域赛(南京) M.Monster Hunter

    2020(ICPC)亚洲区域赛(南京) M.Monster Hunter

    题意

    给定一颗大小为(n)的有根树,每个结点都有点权(hp[i]),选取点的代价是(hp[i] + sum_{son of i} hp[j]),且其父亲也被选

    现在可以在这棵树中删除(0-n)个点,问删除这些点的情况下最小的代价分别是多少

    [2 leq n leq 2 imes 10^3\ 1leq hpleq 10^9 ]

    分析

    树上背包问题

    (f[i][j][k])表示以(i)为根的子树,(i)是否选取,子树中一共选取(j)个点的情况下的最小代价是多少

    转移方程

    [f[x][j + k][1] = min(f[x][j][1]+min(f[v][k][0],f[v][k][1]+hp[v]))\ f[x][j + k][0] = min(f[x][j][0] + min(f[v][k][0],f[v][k][1])) ]

    复杂度的正确性在于任意两点只被枚举到一次,因此复杂度(O(n^2))

    代码

    #include<bits/stdc++.h>
    #define pb push_back
    using namespace std;
    typedef long long ll;
    
    ll rd(){
    	ll x = 0;
    	int f = 1;
    	char ch = getchar();
    	while(ch < '0' || ch > '9'){
    		if(ch == '-') f = -1;
    		ch = getchar();
    	}
    	while(ch >= '0' && ch <= '9'){
    		x = x * 10 + ch - '0';
    		ch = getchar();
    	}
    	return x * f;
    } 
    
    const int maxn = 4005;
    
    int n,m;
    ll p[maxn],hp[maxn];
    vector<int> e[maxn];
    ll f[maxn][maxn][2];
    
    int siz[maxn];
    
    void dfs(int x){
    	f[x][0][0] = 0;
    	f[x][1][1] = hp[x];
    	siz[x] = 1;
    	for(auto v:e[x]){
    		dfs(v);
    		for(int j = siz[x];j >= 0;j--){
    			for(int k = siz[v];k >= 0;k--){
    				f[x][j + k][1] = min(f[x][j + k][1],f[x][j][1] + min(f[v][k][0],f[v][k][1] + hp[v]));
    				f[x][j + k][0] = min(f[x][j + k][0],f[x][j][0] + min(f[v][k][0],f[v][k][1]));
    			}
    		}
    		siz[x] += siz[v];
    	}
    }
    
    void solve(){
    	int n = rd();
    	for(int i = 1;i <= n;i++) e[i].clear();
    	for(int i = 1;i <= n;i++)
    		for(int j = 0;j <= n;j++)
    			f[i][j][0] = f[i][j][1] = 1e18 + 7;
    	for(int i = 2;i <= n;i++){
    		p[i] = rd();
    		e[p[i]].pb(i);
    	}
    	for(int i = 1;i <= n;i++)
    		hp[i] = rd();
    	dfs(1);
    	for(int i = n;i >= 0;i--)
    		printf("%lld ",min(f[1][i][0],f[1][i][1]));
    	puts("");
    }
    
    
    int main(){
    	int T = rd();
    	while(T--)
    		solve();
    }
    
  • 相关阅读:
    Lucene:(一)建立索引文件:2。建立索引文件(一)
    Lucene:(一)建立索引文件:2。建立索引文件(二)Segment文件
    92.外边距设置 Walker
    99.元素居中及样式重置 Walker
    94.外边距踩坑 Walker
    101.列表属性 Walker
    97.boxsizing属性 Walker
    98.溢出隐藏 Walker
    95.内边距设置 Walker
    96.内边距和边框踩坑 Walker
  • 原文地址:https://www.cnblogs.com/hznumqf/p/14295079.html
Copyright © 2011-2022 走看看