• HDU-1011 Starship Troopers (树形DP+分组背包)


    题目大意:给一棵有根带点权树,并且给出容量。求在不超过容量下的最大权值。前提是选完父节点才能选子节点。

    题目分析:树上的分组背包。

    ps:特判m为0时的情况。

    代码如下:

    # include<iostream>
    # include<cstdio>
    # include<vector>
    # include<cstring>
    # include<algorithm>
    using namespace std;
    
    const int N=105;
    const int INF=1000000000;
    
    int n,m;
    int bug[N];
    int w[N];
    int dp[N][N];
    vector<int>e[N];
    
    void init()
    {
    	memset(dp,0,sizeof(dp));
    	for(int i=1;i<=n;++i){
    		scanf("%d%d",bug+i,w+i);
    		e[i].clear();
    	}
    	int a,b;
    	for(int i=1;i<n;++i){
    		scanf("%d%d",&a,&b);
    		e[a].push_back(b);
    		e[b].push_back(a);
    	}
    }
    
    int getTroopers(int x)
    {
    	return (x+19)/20;
    }
    
    int dfs(int u,int fa)
    {
    	int x=getTroopers(bug[u]);
    	for(int i=x;i<=m;++i)
    		dp[u][i]=w[u];
    	for(int i=0;i<e[u].size();++i){
    		int v=e[u][i];
    		if(v==fa) continue;
    		dfs(v,u);
    		for(int j=m;j>=x;--j){
    			for(int k=1;k<=j-x;++k){
    				dp[u][j]=max(dp[u][j],dp[v][k]+dp[u][j-k]);
    			}
    		}
    	}
    }
    
    void solve()
    {
    	if(m==0)
    		printf("0
    ");
    	else{
    		dfs(1,-1);
    		printf("%d
    ",dp[1][m]);
    	}
    }
    
    int main()
    {
    	while(~scanf("%d%d",&n,&m)&&(n!=-1||m!=-1))
    	{
    		init();
    		solve();
    	}
    	return 0;
    }
    

      

  • 相关阅读:
    分词器下载地址
    solr 查询方式
    solr 到 lucene
    Solr 安装与使用 Centos7
    线性表-串:KMP模式匹配算法
    金山——弱智的翻译程序
    FL2440移植Linux2.6.33.7内核
    FL2440移植u-boot2011.09
    【转】C/C++除法实现方式及负数取模详解
    循环缓冲类
  • 原文地址:https://www.cnblogs.com/20143605--pcx/p/5348370.html
Copyright © 2020-2023  润新知