UVA Live Archive 4015 Cave (树形dp,分组背包)
和Heroes Of Might And Magic 相似,题目的询问是dp的一个副产物。
距离是不好表示成状态的,但是可以换一个角度想,如果知道了从一个点向子树走k个结点的最短距离,
那么就可以回答走x距离能访问到的最大结点数量。
当访问了一棵子树,想要访问子树外的结点时,一定要先从子树的根结点出来。
状态可以定义为dp[u][k][?],u表示根节点,k表示访问u的k个子结点,?的取值为0和1表示 不回到u 和 回到u。
不难想到转移过程:
dp[u][k][0] <- dp[u][a][1] + dp[v][b][0] 或 dp[v][b][1] + dp[u][a][0]
dp[u][k][1] <- dp[u][a][1] + dp[v][b][1]
k = a+b+1, v 是 u的子节点
边界为 dp[u][0][0] = dp[u][0][1] = 0表示停留在u.
困难的是转移的顺序,必须保证重复走一个结点只算一次,
实际计算的时候我们只能一个一个的枚举v,对于枚举到v的结点数量b只能从没有考虑过v结点的状态转移。
把结点数量看出物品,v的结点数实际上是一组物品,不能同时选。
剩下和分组背包差不多。
#include<bits/stdc++.h>
using namespace std; #define PS push const int maxn = ;
const int INF = 0x3f3f3f3f; int hd[maxn], nx[maxn], to[maxn], ec;
void add(int u,int v)
{
to[ec] = v;
nx[ec] = hd[u];
hd[u] = ec++;
} int fa[maxn], dist[maxn], deg[maxn], sz[maxn];
int ks;
int n; int dp[maxn][][maxn]; int sol()
{
queue<int> q;
for(int i = ; i < n; i++){
if(!deg[i]) { q.PS(i); }
}
int u;
while(q.size()){
u = q.front(); q.pop();
sz[u] = ;
dp[u][][] = dp[u][][] = ;
for(int i = hd[u]; ~i; i = nx[i]){
int v = to[i];
sz[u] += sz[v];
for(int k = sz[u]-sz[v]; k < sz[u]; k++) dp[u][][k] = dp[u][][k] = INF;
for(int k = sz[u]-; k > ; k--){//从大到小枚举k 保证是上一组的状态转移过来
for(int a = min(sz[v],k)-; a >= ; a--){//先枚举k,然后枚举物品保证组内物品不会同时选到
int b = k--a;
//知道dp[v][b][0] 和 dp[v][b][1] 以后新增加的路径
dp[u][][k] = min(dp[u][][k],min(dp[u][][b]+dp[v][][a]+dist[v],dp[u][][b]+dp[v][][a])+dist[v]);
dp[u][][k] = min(dp[u][][k],dp[u][][b]+dp[v][][a]+dist[v]*);
}
}
}
if(!--deg[fa[u]]) q.PS(fa[u]);//fa[root]虽然不确定,但是在0~500内且deg = 0
}
return u;
} //#define LOCAL
int main()
{
#ifdef LOCAL
freopen("in.txt","r",stdin);
#endif
while(scanf("%d",&n),n){
memset(deg,,sizeof(deg));
memset(hd,-,sizeof(hd)); ec = ;
for(int i = ; i < n; i++){
int u,f,d; scanf("%d%d%d",&u,&f,&d);
fa[u] = f; dist[u] = d;
add(f,u); deg[f]++;
}
printf("Case %d:\n",++ks);
int *ans = dp[sol()][];
int Q; scanf("%d",&Q);
while(Q--){
int x; scanf("%d",&x);
printf("%d\n",upper_bound(ans,ans+n,x)-ans);//能走的最大子结点数+1
}
}
return ;
}
UVA Live Archive 4015 Cave (树形dp,分组背包)的更多相关文章
- HDU4003Find Metal Mineral[树形DP 分组背包]
Find Metal Mineral Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65768/65768 K (Java/Other ...
- HDU-1011 Starship Troopers (树形DP+分组背包)
题目大意:给一棵有根带点权树,并且给出容量.求在不超过容量下的最大权值.前提是选完父节点才能选子节点. 题目分析:树上的分组背包. ps:特判m为0时的情况. 代码如下: # include<i ...
- Ural-1018 Binary Apple Tree(树形dp+分组背包)
#include<cstdio> #include<cstring> #include<iostream> #include<algorithm> #i ...
- 【P2015】二叉苹果树 (树形DP分组背包)
题目描述 有一棵苹果树,如果树枝有分叉,一定是分2叉(就是说没有只有1个儿子的结点) 这棵树共有N个结点(叶子点或者树枝分叉点),编号为1-N,树根编号一定是1. 现在这颗树枝条太多了,需要剪枝.但是 ...
- hdu 1561 树形dp+分组背包
题意:就是给定n个点,每个地点有value[i]的宝物,而且有的宝物必须是另一个宝物取了才能取,问取m个点可以获得的最多宝物价值. 一个子节点就可以返回m个状态,每个状态表示容量为j(j<=m) ...
- poj2486 Apple Tree (树形dp+分组背包)
题目链接:https://vjudge.net/problem/POJ-2486 题意:一棵点权树,起点在1,求最多经过m条边的最大点权和. 思路: 树形dp经典题.用3维状态,dp[u][j][0/ ...
- hdu1561 The more, The Better 树形DP+分组背包
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1561 思路: 典型的树形背包题目: 定义dp[i][j]表示以i为根节点,攻打j个城堡的获得的财宝的最 ...
- hdu 4003 树形dp+分组背包 2011大连赛区网络赛C
题意:求K个机器人从同一点出发,遍历所有点所需的最小花费 链接:点我 Sample Input 3 1 1 //3个点,从1出发,1个机器人 1 2 1 1 3 1 3 1 2 1 2 1 1 3 1 ...
- HDU-4003 Find Metal Mineral (树形DP+分组背包)
题目大意:用m个机器人去遍历有n个节点的有根树,边权代表一个机器人通过这条边的代价,求最小代价. 题目分析:定义状态dp(root,k)表示最终遍历完成后以root为根节点的子树中有k个机器人时产生的 ...
随机推荐
- PHP中的继承
<?php class Bar { private $salary = 3000; public $lunch = 1000; // php中关于“可见性”的概念 public function ...
- Codeforces Round #558 (Div. 2)C(计算几何,排列组合,模拟)
#include<bits/stdc++.h>using namespace std;typedef struct{ double k,b;}node;node k[1000007];bo ...
- oracle批量插入带主键自增
https://blog.csdn.net/qq_37630354/article/details/82792288
- 老男孩Day1作业(一):编写登录接口
需求:编写登陆接口1. 用户输入帐号密码进行登陆2. 用户信息保存在文件内3. 用户密码输入错误三次后锁定用户 1)编写思路 编写思路参考下面GitHub链接中的流程图 https://github. ...
- Codeforces Round #363 (Div. 2) C
Description Vasya has n days of vacations! So he decided to improve his IT skills and do sport. Vasy ...
- HelloSpock
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/20 ...
- java运行环境和配置环境
1.配置JAVA_HOME,CLASSPATH,PATH的意义 JAVA_HOME:指向jdk的安装目录,意义不多说. PATH:作用是指向javac编译器,将java编译成 .class文件. CL ...
- mysql隔离级别与锁,接口并发响应速度的关系(2)
innoDB默认隔离级别 mysql> SELECT @@tx_isolation; +-----------------+ | @@tx_isolation | +-------------- ...
- 【ACM】阶乘之和 - 避免重复计算
阶乘之和 时间限制:3000 ms | 内存限制:65535 KB 难度:3 描述 给你一个非负数整数n,判断n是不是一些数(这些数不允许重复使用,且为正数)的阶乘之和,如9=1!+2!+3! ...
- $.getScript("/Scripts/js/video.min.js");
js内引用JS: $.getScript("/Scripts/js/video.min.js");