hdu 4003 Find Metal Mineral(树形DP+分组背包,每个物品必须只能选一次)

本文主要是介绍hdu 4003 Find Metal Mineral(树形DP+分组背包,每个物品必须只能选一次),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

1、http://acm.hdu.edu.cn/showproblem.php?pid=4003

2、题目大意:

一棵树有n个结点,根节点是s,在树上放k个机器人,现在使得k个机器人将所有结点遍历一遍最小的代价是多少?

dp[i][j]表示以i为根节点放j个机器人消耗的最小代价,

因为必须选择选择每个分组中的一个,我们可以将dp[u][0]先放进去,如果有更好的再替换它

for(int j=m;j>=0;j--)
            {
                dp[u][j]+=dp[vv][0]+w[i]*2;
                for(int k=1;k<=j;k++)
                {
                    dp[u][j]=min(dp[u][j],dp[u][j-k]+dp[vv][k]+k*w[i]);
                }
            }

3、AC代码;

#include<stdio.h>
#include<string.h>
#include<algorithm>
using namespace std;
#define N 10005
int head[N*2],next[N*2],v[N*2],w[N*2];
int tot,m;
int dp[N][15];
void add_edge(int a,int b,int c)
{v[tot]=b;w[tot]=c;next[tot]=head[a];head[a]=tot++;
}
void dfs(int u,int fa)
{for(int i=head[u];i!=-1;i=next[i]){int vv=v[i];if(vv!=fa){dfs(vv,u);for(int j=m;j>=0;j--){//先将dp[vv][0]放进去,如果有更好的再将它替换,保证每组中都选一个dp[u][j]+=dp[vv][0]+w[i]*2;for(int k=1;k<=j;k++){dp[u][j]=min(dp[u][j],dp[u][j-k]+dp[vv][k]+k*w[i]);}}}}
}
int main()
{int n,s,a,b,c;while(scanf("%d%d%d",&n,&s,&m)!=EOF){tot=0;memset(head,-1,sizeof(head));memset(dp,0,sizeof(dp));for(int i=1;i<n;i++){scanf("%d%d%d",&a,&b,&c);add_edge(a,b,c);add_edge(b,a,c);}dfs(s,-1);printf("%d\n",dp[s][m]);}return 0;
}


 

这篇关于hdu 4003 Find Metal Mineral(树形DP+分组背包,每个物品必须只能选一次)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/369689

相关文章

使用C#如何创建人名或其他物体随机分组

《使用C#如何创建人名或其他物体随机分组》文章描述了一个随机分配人员到多个团队的代码示例,包括将人员列表随机化并根据组数分配到不同组,最后按组号排序显示结果... 目录C#创建人名或其他物体随机分组此示例使用以下代码将人员分配到组代码首先将lstPeople ListBox总结C#创建人名或其他物体随机分组

电脑多久清理一次灰尘合? 合理清理电脑上灰尘的科普文

《电脑多久清理一次灰尘合?合理清理电脑上灰尘的科普文》聊起电脑清理灰尘这个话题,我可有不少话要说,你知道吗,电脑就像个勤劳的工人,每天不停地为我们服务,但时间一长,它也会“出汗”——也就是积累灰尘,... 灰尘的堆积几乎是所有电脑用户面临的问题。无论你的房间有多干净,或者你的电脑是否安装了灰尘过滤器,灰尘都

【前端学习】AntV G6-08 深入图形与图形分组、自定义节点、节点动画(下)

【课程链接】 AntV G6:深入图形与图形分组、自定义节点、节点动画(下)_哔哩哔哩_bilibili 本章十吾老师讲解了一个复杂的自定义节点中,应该怎样去计算和绘制图形,如何给一个图形制作不间断的动画,以及在鼠标事件之后产生动画。(有点难,需要好好理解) <!DOCTYPE html><html><head><meta charset="UTF-8"><title>06

poj2576(二维背包)

题意:n个人分成两组,两组人数只差小于1 , 并且体重只差最小 对于人数要求恰好装满,对于体重要求尽量多,一开始没做出来,看了下解题,按照自己的感觉写,然后a了 状态转移方程:dp[i][j] = max(dp[i][j],dp[i-1][j-c[k]]+c[k]);其中i表示人数,j表示背包容量,k表示输入的体重的 代码如下: #include<iostream>#include<

hdu2159(二维背包)

这是我的第一道二维背包题,没想到自己一下子就A了,但是代码写的比较乱,下面的代码是我有重新修改的 状态转移:dp[i][j] = max(dp[i][j], dp[i-1][j-c[z]]+v[z]); 其中dp[i][j]表示,打了i个怪物,消耗j的耐力值,所得到的最大经验值 代码如下: #include<iostream>#include<algorithm>#include<

csu(背包的变形题)

题目链接 这是一道背包的变形题目。好题呀 题意:给n个怪物,m个人,每个人的魔法消耗和魔法伤害不同,求打死所有怪物所需的魔法 #include<iostream>#include<algorithm>#include<cstring>#include<stack>#include<queue>#include<set>//#include<u>#include<map

hdu4826(三维DP)

这是一个百度之星的资格赛第四题 题目链接:http://acm.hdu.edu.cn/contests/contest_showproblem.php?pid=1004&cid=500 题意:从左上角的点到右上角的点,每个点只能走一遍,走的方向有三个:向上,向下,向右,求最大值。 咋一看像搜索题,先暴搜,TLE,然后剪枝,还是TLE.然后我就改方法,用DP来做,这题和普通dp相比,多个个向上

hdu1011(背包树形DP)

没有完全理解这题, m个人,攻打一个map,map的入口是1,在攻打某个结点之前要先攻打其他一个结点 dp[i][j]表示m个人攻打以第i个结点为根节点的子树得到的最优解 状态转移dp[i][ j ] = max(dp[i][j], dp[i][k]+dp[t][j-k]),其中t是i结点的子节点 代码如下: #include<iostream>#include<algorithm

hdu1171(母函数或多重背包)

题意:把物品分成两份,使得价值最接近 可以用背包,或者是母函数来解,母函数(1 + x^v+x^2v+.....+x^num*v)(1 + x^v+x^2v+.....+x^num*v)(1 + x^v+x^2v+.....+x^num*v) 其中指数为价值,每一项的数目为(该物品数+1)个 代码如下: #include<iostream>#include<algorithm>

hdu4865(概率DP)

题意:已知前一天和今天的天气概率,某天的天气概率和叶子的潮湿程度的概率,n天叶子的湿度,求n天最有可能的天气情况。 思路:概率DP,dp[i][j]表示第i天天气为j的概率,状态转移如下:dp[i][j] = max(dp[i][j, dp[i-1][k]*table2[k][j]*table1[j][col] )  代码如下: #include <stdio.h>#include