zoukankan      html  css  js  c++  java
  • hihoCoder#1055 : 刷油漆 (树形DP+01背包)

    题目大意:给一棵带点权的树,现在要从根节点开始选出m个连通的节点,使总权值最大。

    题目分析:定义状态dp(u,m)表示在以u为根的子树从根节点开始选出m个点连通的最大总权值,则dp(u,m)=max(dp(u,m),dp(u,m-k)+dp(son,k)),其中0<=k<m。这是01背包,k应该从大往小枚举。

    代码如下:

    # include<iostream>
    # include<cstdio>
    # include<cmath>
    # include<vector>
    # include<list>
    # include<queue>
    # include<map>
    # include<set>
    # include<cstring>
    # include<algorithm>
    using namespace std;
    
    const int N=1000;
    const int INF=1000000000;
    const double inf=1e20;
    
    int n,m;
    int w[105];
    vector<int>e[105];
    int dp[105][105];
    
    void dfs(int u,int fa)
    {
    	fill(dp[u],dp[u]+m+1,w[u]);
    	dp[u][0]=0;
    	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>=2;--j){
    			for(int k=j-1;k>=0;--k)
    				dp[u][j]=max(dp[u][j],dp[u][j-k]+dp[v][k]);
    		}
    	}
    }
    
    int main()
    {
    	while(~scanf("%d%d",&n,&m))
    	{
    		for(int i=0;i<n;++i){
    			scanf("%d",w+i);
    			e[i].clear();
    		}
    		int a,b;
    		for(int i=1;i<n;++i){
    			scanf("%d%d",&a,&b);
    			--a,--b;
    			e[a].push_back(b);
    			e[b].push_back(a);
    		}
    		dfs(0,-1);
    		printf("%d
    ",dp[0][m]);
    	}
    	return 0;
    }
    

      

  • 相关阅读:
    ab参数详解 – 压力测试
    configure/make/make install的作用
    LNMP第二部分nginx、php配置
    centos 6.9安装mysql
    HDFS Java API的使用举例
    配置SSH无秘钥登录
    一篇文章学懂Shell脚本
    自己实现一个简单的网购秒杀系统
    hadoop伪分布式环境搭建
    vmware虚拟机的克隆
  • 原文地址:https://www.cnblogs.com/20143605--pcx/p/5485127.html
Copyright © 2011-2022 走看看