• Gym102292M.Monster Hunter(树形背包+滚动数组)


    题意:

    给出一棵n个点的树。

    只有把一个点的父节点们全部消灭了才能消灭这个点。

    消灭一个点的代价是它本身的生命值和它子节点的生命值之和。

    同时你也可以用魔法0代价消灭任意一个点。

    询问使用k次魔法,消灭所有点的最小代价。输出k=0到n的答案。

    题解:

    定义(f(i,j,k))表示第(i)个点的子树内有(j)个节点被魔法消灭时,第(i)个节点自己是否用魔法消灭所能得到的最小代价。

    这样就可以对每个点的叶子做树形背包。

    但是一开始怎么搞都弄不过样例。

    看了别人的博客后才发现,如果直接这样定义状态会导致一些状态的复用,需要再加一维x表示仅考虑当前节点的前x个儿子。

    这样就是(f(i,j,k,x))表示第i个点的子树内有j个节点被魔法消灭时,第i个节点自己是否用魔法消灭所得到的最小代价,仅考虑前x个儿子。

    可以把x这一维滚动掉,注意滚动数组每一轮要清空。

    #include<bits/stdc++.h>
    using namespace std;
    const int maxn=2005;
    const long long inf=1e13;
    typedef long long ll;
    int n,a[maxn];
    vector<int> g[maxn];
    ll f[maxn][maxn][2][2];//第i个点的子树内用魔法删除j个点,同时第i个点本身是否用魔法删除,当前考虑前k个叶子(滚动数组) 
    
    int size[maxn];
    int e[maxn];
    void dfs (int x) {
    	size[x]=1;
    	int k=0;
    	f[x][0][0][k]=a[x];
    	f[x][1][1][k]=0;
    	for (int y:g[x]) {
    		dfs(y);
    		for (int i=0;i<=size[x]+size[y];i++) f[x][i][0][k^1]=f[x][i][1][k^1]=inf;
    		for (int i=0;i<=size[x];i++) {
    			for (int j=0;j<=size[y];j++) {
    				f[x][i+j][0][k^1]=min(f[x][i+j][0][k^1],f[x][i][0][k]+min(f[y][j][0][e[y]]+a[y],f[y][j][1][e[y]]));
    				f[x][i+j][1][k^1]=min(f[x][i+j][1][k^1],f[x][i][1][k]+min(f[y][j][0][e[y]],f[y][j][1][e[y]]));
    			}
    		}
    		k^=1;
    		size[x]+=size[y];
    	}
    	e[x]=k;
    }
    
    int main () {
    	int _;
    	scanf("%d",&_);
    	while (_--) {
    		scanf("%d",&n);
    		for (int i=0;i<=n;i++) g[i].clear();
    		for (int i=0;i<=n;i++) for (int j=0;j<=n*2;j++) for (int k=0;k<2;k++) for (int x=0;x<2;x++) f[i][j][k][x]=inf;
    		for (int i=2;i<=n;i++) {
    			int x;
    			scanf("%d",&x);
    			g[x].push_back(i);
    		}
    		for (int i=1;i<=n;i++) scanf("%d",a+i);
    		dfs(1);
    		for (int i=0;i<=n;i++) {
    			if (i) printf(" ");
    			printf("%lld",min(f[1][i][0][e[1]],f[1][i][1][e[1]]));
    		}
    		printf("
    ");
    	}
    }
     
    
  • 相关阅读:
    python virtualenv
    ICMP
    正则表达式
    tcpdump命令
    vim命令
    IP网际协议
    链路层
    python模块学习 logging
    Angular2+如何去除url中的#
    angular5懒加载之模块划分
  • 原文地址:https://www.cnblogs.com/zhanglichen/p/14603471.html
Copyright © 2020-2023  润新知