Find Metal Mineral

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65768/65768 K (Java/Others) Total Submission(s): 2371    Accepted Submission(s): 1079

Problem Description
  Humans  have  discovered  a  kind  of  new  metal  mineral  on  Mars  which  are  distributed  in point‐like  with  paths  connecting  each  of  them  which  formed  a  tree.  Now  Humans  launches  k robots on Mars to collect them, and due to the unknown reasons, the landing site S of all robots is identified in advanced, in other word, all robot should start their job at point S. Each robot can return  to  Earth  anywhere,  and  of  course  they  cannot  go  back  to  Mars.  We  have  research  the information of all paths on Mars, including its two endpoints x, y and energy cost w. To reduce the total energy cost, we should make a optimal plan which cost minimal energy cost.
 
Input
  There are multiple cases in the input. In each case: The first line specifies three integers N, S, K specifying the numbers of metal mineral, landing site and the number of robots. The  next  n‐1  lines  will  give  three  integers  x,  y,  w  in  each  line  specifying  there  is  a  path connected point x and y which should cost w. 1<=N<=10000, 1<=S<=N, 1<=k<=10, 1<=x, y<=N, 1<=w<=10000.
Output
  For each cases output one line with the minimal energy cost.
Sample Input

3 1 1 1 2 1 1 3 1 3 1 2 1 2 1 1 3 1

Sample Output
3 2

Hint

In the first case: 1->2->1->3 the cost is 3; In the second case: 1->2; 1->3 the cost is 2;

dp[pos][num]表示以pos为根节点的子树下,用去num个机器人,所得到的最小值

特别的是当num==0的时候,dp[pos][0]表示用一个机器人去走完所有子树,最后又回到pos这个节点

状态转移:dp[pos][num]=min∑{dp[pos_j][num_j]+w_j},pos_j是pos的所有儿子,

当num_j==0的时候,和别的时候不同,特别处理一下就好。

状态转移并不难,最精华的,我不认为是状态转移,而是转移时使用的那个“分组背包”思想。

使用一维数组的“分组背包”伪代码如下:

for 所有的组i

for v=V..0

for 所有的k属于组i

f[v]=max{f[v],f[v-c[k]]+w[k]}

上面那个状态转移时,要把num个机器人分给所有它的儿子,状态太多了,不好做,用“分组背包”实在太帅了。
 #include <iostream>
#include <cstdio>
#include <cstring> using namespace std; struct Edge{
int to;
int value;
int next;
}edge[*];
int head[],dp[][];
int N,S,K,total; inline int MIN(int a,int b)
{
if(a<b) return a;
return b;
}
void addEdge(int start,int end,int value)
{
edge[total].to=end;edge[total].value=value;
edge[total].next=head[start];head[start]=total++; edge[total].to=start,edge[total].value=value;
edge[total].next=head[end],head[end]=total++;
} void DP(int source,int pre)
{
for(int i=head[source];i!=-;i=edge[i].next)
{
int to=edge[i].to;
if(to==pre) continue;
DP(to,source);
for(int j=K;j>=;j--)
{
dp[source][j]+=dp[to][]+*edge[i].value;
for(int k=;k<=j;k++)
dp[source][j]=MIN(dp[source][j],dp[source][j-k]+dp[to][k]+k*edge[i].value);
}
}
} int main()
{
while(scanf("%d %d %d",&N,&S,&K)!=EOF)
{
memset(dp,,sizeof(dp));
memset(head,-,sizeof(head));
total=; int x,y,cost;
for(int i=;i<N;i++)
{
scanf("%d %d %d",&x,&y,&cost);
addEdge(x,y,cost);
}
DP(S,-);
printf("%d\n",dp[S][K]);
}
return ;
}

思路和其他人差不多,谈谈自己是怎么理解的吧:
     首先,用两数组建立无向树,还是第一次,费了不少功夫。定义一个结构代表边edge[i]={to,next,value},其中edge[i]表示第i条边,to是边的末点,value就不说了,next代表的是同一父节点边方向相同的与此边相邻的左边的边的编号,其中最左是-1。以此为基础建立一个边数组(注意数组大小是顶点数的两倍),还有用一个head[i]数组来表示最右边的边的编号。

  解释这一段代码,当时写的理解的不是很好:

 void DP(int source,int pre)
{
for(int i=head[source];i!=-;i=edge[i].next)
{
int to=edge[i].to;
if(to==pre) continue;
DP(to,source);
for(int j=K;j>=;j--)
{
dp[source][j]+=dp[to][]+*edge[i].value;
for(int k=;k<=j;k++)
dp[source][j]=MIN(dp[source][j],dp[source][j-k]+dp[to][k]+k*edge[i].value);
}
}
}

第一层for循环查找与节点source相连的各条边,to是此边对应的末点,若此边是叶子节点则to==pre(由于节点最左边的边访问完以后,只有到他父节点的边,这里只能用continue,因为不确定访问的顺序,return不合适),递归访问子节点此时应用01背包,由于dp[source][0]比较特殊单独处理,一棵子树对应一个分组,dp[source][j]=MIN(dp[source][j],dp[source][j-k]+dp[to][k]+k*edge[i].value);也比较好理解。

树形DP-----HDU4003 Find Metal Mineral的更多相关文章

  1. 【树形dp】Find Metal Mineral

    [HDU4003]Find Metal Mineral Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65768/65768 K (J ...

  2. HDU4003 Find Metal Mineral 树形DP

    Find Metal Mineral Problem Description Humans have discovered a kind of new metal mineral on Mars wh ...

  3. HDU-4003 Find Metal Mineral 树形DP (好题)

    题意:给出n个点的一棵树,有k个机器人,机器人从根节点rt出发,问访问完整棵树(每个点至少访问一次)的最小代价(即所有机器人路程总和),机器人可以在任何点停下. 解法:这道题还是比较明显的能看出来是树 ...

  4. HDU4003 Find Metal Mineral

    看别人思路的 树形分组背包. 题意:给出结点数n,起点s,机器人数k,然后n-1行给出相互连接的两个点,还有这条路线的价值,要求最小花费 思路:这是我从别人博客里找到的解释,因为很详细就引用了 dp[ ...

  5. HDU-4003 Find Metal Mineral (树形DP+分组背包)

    题目大意:用m个机器人去遍历有n个节点的有根树,边权代表一个机器人通过这条边的代价,求最小代价. 题目分析:定义状态dp(root,k)表示最终遍历完成后以root为根节点的子树中有k个机器人时产生的 ...

  6. HDU4003Find Metal Mineral[树形DP 分组背包]

    Find Metal Mineral Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65768/65768 K (Java/Other ...

  7. hdu 4003 Find Metal Mineral 树形DP

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4003 Humans have discovered a kind of new metal miner ...

  8. hdu 4003 Find Metal Mineral 树形dp ,*****

    Find Metal Mineral Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65768/65768 K (Java/Other ...

  9. HDU 4003 Find Metal Mineral(分组背包+树形DP)

    题目链接 很棒的一个树形DP.学的太渣了. #include <cstdio> #include <string> #include <cstring> #incl ...

  10. hdu4003详解(树形dp+多组背包)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4003 Find Metal Mineral Time Limit: 2000/1000 MS (Jav ...

随机推荐

  1. selenium - xpath - 定位

    前言: XPath 是一门在 XML 文档中查找信息的语言.XPath 可用来在 XML 文档中对元素和属性进行遍历. 看这里介绍:w3school 首先来看一下xpath常用的语法: 一.xpath ...

  2. firstModel权限问题

    laravel根目录下没有 .env , 执行 cp .env.example .envstorage和bootstrap/cache 没有给写入权限, 执行 chmod -R 777 storage ...

  3. awk常见基本使用

    -F 指定分割符号 print 外层的引号必须是单引号 $n不能被解析 [root@bogon ~]# .txt a:b:c:d a1:b1:c1:d1 a2:b2:c2:d2 a_: :c:dddd ...

  4. JavaScript笔记——面向对象与原型

    JavaScript也是一门面向对象的语言.面向对象的语言有一个标志,那就是类的概念,而通过类可以创建任意多个具有相同属性和方法的对象.但是,JavaScript竟然没有class,因此它的面向对象也 ...

  5. Handler消息传送机制

    一.什么是UI线程 当程序第一次启动的时候,Android会同时启动一条主线程( Main Thread). 主要负责处理与UI相关的事件. 二.UI线程存在的问题 出于性能优化考虑,Android的 ...

  6. mysql字符类型

    字符类型 #官网:https://dev.mysql.com/doc/refman/5.7/en/char.html #注意:char和varchar括号内的参数指的都是字符的长度 #char类型:定 ...

  7. 完整部署OpenStack-memcache配置

    一.[root@openstack-server ~]# nova listERROR (CommandError): You must provide a username or user id v ...

  8. Python Twisted系列教程11:改进诗歌下载服务器

    作者:dave@http://krondo.com/your-poetry-is-served/ 译者:杨晓伟(采用意译) 你可以从这里从头阅读这个系列. 诗歌下载服务器 到目前为止,我们已经学习了大 ...

  9. puclic 页面公共CSS样式

    body, div, dl, dt, dd, ul, ol, li, pre, form, fieldset, blockquote, h1, h2, h3, h4, h5, h6,p{ paddin ...

  10. 如何重置Oracle服务器ILOM中root用户的密码

    在ILOM中,root用户的缺省密码是changeme. 为了系统的安全性,通常情况下需要修改root密码.  如果忘了密码,可以参考以下步骤重置root密码. 用串口线连接Oracle服务器ILOM ...