HDU4003 Find Metal Mineral
看别人思路的
树形分组背包。
题意:给出结点数n,起点s,机器人数k,然后n-1行给出相互连接的两个点,还有这条路线的价值,要求最小花费
思路:这是我从别人博客里找到的解释,因为很详细就引用了
dp[i][j]表示对于以i结点为根结点的子树,放j个机器人所需要的权值和。
当j=0时表示放了一个机器人下去,遍历完结点后又回到i结点了。状态转移方程类似背包
如果最终的状态中以i为根结点的树中有j(j>0)个机器人,那么不可能有别的机器人r到了这棵树后又跑到别的树中去
因为那样的话,一定会比j中的某一个到达i后跑与r相同的路径再回到i,再接着跑它的路径要差(多了一条i回去的边)
这样的话,如果最后以i为根结点的树中没有机器人,那么只可能是派一个机器人下去遍历完后再回来
可以这么理解:
对于每个根节点root,有个容量为K的背包
如果它有i个儿子,那么就有i组物品,价值分别为dp[son][0],dp[son][1].....dp[son][k] ,这些物品的重量分别为0,1,.....k
现在要求从每组里选一个物品(且必须选一个物品)装进root的背包,使得容量不超过k的情况下价值最大。
那么这就是个分组背包的问题了。
但是这里有一个问题,就是每组必须选一个物品。
对于这个的处理,我们先将dp[son][0]放进背包,如果该组里有更好的选择,那么就会换掉这个物品,否则的话这个物品就是最好的选择。这样保证每组必定选了一个。
Find Metal Mineral
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65768/65768 K (Java/Others) Total Submission(s): 2198 Accepted Submission(s): 1001
#include <stdio.h>
#include<iostream>
#include <string.h>
#include <algorithm>
using namespace std;
struct node
{
int now,next,val;
}tree[20005];
int len,n,s,k;
int head[10005],dp[10005][15],vis[10005];
void add(int x,int y,int v)
{
tree[len].now=y;
tree[len].val=v;
tree[len].next=head[x];
head[x]=len++;
}
void dfs(int root,int p)
{
int i,j,q,son;
vis[root]=1;
for(i=head[root];i!=-1;i=tree[i].next)
{
son=tree[i].now;
if(son==p)
continue;
if(!vis[son])
{
dfs(son,root);
for(j=k;j>=0;j--)
{
dp[root][j]+=dp[son][0]+2*tree[i].val;//先将dp[son][0]放进背包,
//由于dp[son][0]是表示用一个机器人去走完所有子树,
//最后又回到pos这个节点,所以花费要乘以2
for(q=1;q<=j;q++)//在这里找到比dp[son][0]更优的方案,分组背包
dp[root][j]=min(dp[root][j],dp[root][j-q]+dp[son][q]+q*tree[i].val);
//必须是乘以p,p以前的价值要加上。
}
}
}
} int main()
{
int i,x,y,w;
while(~scanf("%d%d%d",&n,&s,&k))
{
memset(dp,0,sizeof(dp));
memset(head,-1,sizeof(head));
memset(vis,0,sizeof(vis));
len=0;
for(i=1;i<n;i++)
{
scanf("%d%d%d",&x,&y,&w);
add(x,y,w);
add(y,x,w);
}
dfs(s,-1);
printf("%d\n",dp[s][k]);
}
return 0;
}
HDU4003 Find Metal Mineral的更多相关文章
- HDU4003 Find Metal Mineral 树形DP
Find Metal Mineral Problem Description Humans have discovered a kind of new metal mineral on Mars wh ...
- HDU-4003 Find Metal Mineral (树形DP+分组背包)
题目大意:用m个机器人去遍历有n个节点的有根树,边权代表一个机器人通过这条边的代价,求最小代价. 题目分析:定义状态dp(root,k)表示最终遍历完成后以root为根节点的子树中有k个机器人时产生的 ...
- HDU-4003 Find Metal Mineral 树形DP (好题)
题意:给出n个点的一棵树,有k个机器人,机器人从根节点rt出发,问访问完整棵树(每个点至少访问一次)的最小代价(即所有机器人路程总和),机器人可以在任何点停下. 解法:这道题还是比较明显的能看出来是树 ...
- 【树形dp】Find Metal Mineral
[HDU4003]Find Metal Mineral Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65768/65768 K (J ...
- HDU4003Find Metal Mineral[树形DP 分组背包]
Find Metal Mineral Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65768/65768 K (Java/Other ...
- hdu 4003 Find Metal Mineral 树形DP
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4003 Humans have discovered a kind of new metal miner ...
- hdu 4003 Find Metal Mineral 树形dp ,*****
Find Metal Mineral Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65768/65768 K (Java/Other ...
- 树形DP-----HDU4003 Find Metal Mineral
Find Metal Mineral Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65768/65768 K (Java/Other ...
- HDOJ 4003 Find Metal Mineral
题意: 一棵有权树,从根结点中放入 K 个机器人.求用这 K 个机器人遍历全部的结点最少的权值和. 思路: 1. dp[u][i] 表示给以 u 为根节点的子树放 i 个机器人,遍历其子树所须要的最小 ...
随机推荐
- JAAS - Document
JAAS 参考文档: JAAS Reference Guide JAAS Authentication Tutorial JAAS Authorization Tutorial LoginModule ...
- python爬虫scrapy的Selectors参考文档
http://doc.scrapy.org/en/1.0/topics/selectors.html#topics-selectors-htmlcode
- 同一台电脑上安装两个tomcat服务器
1.下载免安装版tomcat,解压成tomcat1.tomcat2: 2.修改tomcat2中conf下server.xml文件如下: <Server port="8005" ...
- (java)从零开始之--异常处理(以文件拷贝为例)
开发过程中避免不了对异常的处理,但是异常的处理又不能乱throw 下面是简单的抛异常处理 public static void CopyFile(String souFile,String dirFi ...
- 【算法】数组与矩阵问题——找到无序数组中最小的k个数
/** * 找到无序数组中最小的k个数 时间复杂度O(Nlogk) * 过程: * 1.一直维护一个有k个数的大根堆,这个堆代表目前选出来的k个最小的数 * 在堆里的k个元素中堆顶的元素是最小的k个数 ...
- hdoj 1089(费马小定理)
题目大意:方程f(x)=5*x^13+13*x^5+k*a*x:输入任意一个数k,是否存在一个数a,对任意x都能使得f(x)能被65整出. 现假设存在这个数a ,因为对于任意x方程都成立 所以,当x= ...
- Oauth认证简介
Oauth是什么: 1.Oauth是一种安全认证的协议: 2.Oauth为用户资源的授权提供了一个安全的.开放而又简易的标准: 3.Oauth的授权不会使第三方触及到用户的账号信息(用户名和密码). ...
- js 之 复制一段代码
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...
- .Net用js实现aspx页面删除TextBox输入框的前后空格
去掉TextBox输入框两头的前后空格:onblur="this.value=this.value.replace(/^\s+|\s+$/g,'');" str为要去除空格的字符串 ...
- css去除webkit内核的默认样式
做移动端的朋友应该知道,iphone的默认按钮是个很恶心的圆角,select下拉框也有默认样式无法修改. 这时候可以用到 -webkit-appearance:none //去除默认样 在按钮和sel ...