动态规划(树形DP):LNOI 2016 侦察守卫



Sample Input
12 2
8 9 12 6 1 1 5 1 4 8 10 6
10
1 2 3 5 6 7 8 9 10 11
1 3
2 3
3 4
4 5
4 6
4 7
7 8
8 9
9 10
10 11
11 12
Sample Output
10
这道题考虑树形DP,dp[x][i]表示由此点向下走i步到达的点监控,由于有的点不需要被监控,再开一个变量记录即可,转移并不复杂,推一推就出来了。
可能我的代码有瑕疵,有些地方可能不必要(毕竟DP有时候想不清),但是不影响正确性。
#include <iostream>
#include <cstring>
#include <cstdio>
#define dp(x,y) dp[x][y+20]
using namespace std;
const int N=,D=,INF=;
int n,m,d,w[N],dp[N][D*],f[N];bool vis[N];
int cnt,fir[N],to[N*],nxt[N*];
void addedge(int a,int b){
nxt[++cnt]=fir[a];to[fir[a]=cnt]=b;
nxt[++cnt]=fir[b];to[fir[b]=cnt]=a;
} int st[N],top;
int m1[N],m2[N];
void DP(int x,int fa){
int flag=;
for(int i=fir[x];i;i=nxt[i])
if(to[i]!=fa)flag=,DP(to[i],x); if(!flag){
f[x]=vis[x]?INF:;dp(x,)=w[x];
for(int i=;i<=d;i++)dp(x,i)=INF;
return;
} top=;
for(int i=fir[x];i;i=nxt[i])
if(to[i]!=fa)st[++top]=to[i]; //处理f[x]
if(!vis[x])
for(int i=,M;i<=top;i++){
M=f[st[i]];
for(int j=;j<=d;j++)
M=min(M,dp(st[i],j));
f[x]+=M;
}
else f[x]=INF; //处理dp(x,0)
dp(x,)=w[x];
for(int i=,M;i<=top;i++){
M=f[st[i]];
for(int j=-d;j<=d;j++)
M=min(M,dp(st[i],j));
dp(x,)+=M;
} //处理向上看的
for(int i=;i<=top;i++){
m2[i]=f[st[i]];
for(int j=;j<=d;j++)
m2[i]=min(m2[i],dp(st[i],j));
m1[i]=INF;
} for(int i=-d;i<=-;i++)
for(int j=;j<=top;j++){
dp(x,i)+=min(m1[j],m2[j]);
m1[j]=min(m1[j],dp(st[j],i));
} //处理向下看的
for(int i=;i<=top;i++){
m2[i]=f[st[i]];
for(int j=;j<=d;j++)
m2[i]=min(m2[i],dp(st[i],j));
m1[i]=INF;
} for(int i=d,M;i>=;i--){
M=-INF;
for(int j=;j<=top;j++){
dp(x,i)+=min(m1[j],m2[j]);
M=max(M,min(m1[j],m2[j])-dp(st[j],i-));
m1[j]=min(m1[j],dp(st[j],-i));
}
dp(x,i)-=M;
}
} int main(){
freopen("observer.in","r",stdin);
freopen("observer.out","w",stdout);
scanf("%d%d",&n,&d);
for(int i=;i<=n;i++)
scanf("%d",&w[i]);
scanf("%d",&m);
for(int i=,x;i<=m;i++){
scanf("%d",&x);
vis[x]=true;
}
for(int i=,a,b;i<n;i++){
scanf("%d%d",&a,&b);
addedge(a,b);
}
DP(,);
int ans=f[];
for(int i=;i<=d;i++)
ans=min(ans,dp(,i));
printf("%d\n",ans);
return ;
}
动态规划(树形DP):LNOI 2016 侦察守卫的更多相关文章
- 动态规划——树形dp
动态规划作为一种求解最优方案的思想,和递归.二分.贪心等基础的思想一样,其实都融入到了很多数论.图论.数据结构等具体的算法当中,那么这篇文章,我们就讨论将图论中的树结构和动态规划的结合——树形dp. ...
- UOJ#290. 【ZJOI2017】仙人掌 仙人掌,Tarjan,计数,动态规划,树形dp,递推
原文链接https://www.cnblogs.com/zhouzhendong/p/UOJ290.html 题解 真是一道好题! 首先,如果不是仙人掌直接输出 0 . 否则,显然先把环上的边删光. ...
- 洛谷 P3267 - [JLOI2016/SHOI2016]侦察守卫(树形 dp)
洛谷题面传送门 经典题一道,下次就称这种"覆盖距离不超过 xxx 的树形 dp"为<侦察守卫模型> 我们考虑树形 \(dp\),设 \(f_{x,j}\) 表示钦定了 ...
- [BZOJ 4455] [ZJOI 2016] 小星星 (树形dp+容斥原理+状态压缩)
[BZOJ 4455] [ZJOI 2016] 小星星 (树形dp+容斥原理+状态压缩) 题面 给出一棵树和一个图,点数均为n,问有多少种方法把树的节点标号,使得对于树上的任意两个节点u,v,若树上u ...
- 树形DP——动态规划与数据结构的结合,在树上做DP
本文始发于个人公众号:TechFlow,原创不易,求个关注 今天是算法与数据结构的第15篇,也是动态规划系列的第4篇. 之前的几篇文章当中一直在聊背包问题,不知道大家有没有觉得有些腻味了.虽然经典的文 ...
- 【动态规划】树形DP完全详解!
蒟蒻大佬时隔三个月更新了!!拍手拍手 而且是更新了几篇关于DP的文章(RioTian狂喜) 现在赶紧学习和复习一下树形DP.... 树形DP基础:Here,CF上部分树形DP练习题:Here \[QA ...
- COGS 2532. [HZOI 2016]树之美 树形dp
可以发现这道题的数据范围有些奇怪,为毛n辣么大,而k只有10 我们从树形dp的角度来考虑这个问题. 如果我们设f[x][k]表示与x距离为k的点的数量,那么我们可以O(1)回答一个询问 可是这样的话d ...
- 动态规划(树形DP):HDU 5834 Magic boy Bi Luo with his excited tree
aaarticlea/png;base64,iVBORw0KGgoAAAANSUhEUgAAA8UAAAJbCAIAAABCS6G8AAAgAElEQVR4nOy9fXQcxZ0uXH/hc8i5N+
- 树形动态规划(树形DP)入门问题—初探 & 训练
树形DP入门 poj 2342 Anniversary party 先来个题入门一下~ 题意: 某公司要举办一次晚会,但是为了使得晚会的气氛更加活跃,每个参加晚会的人都不希望在晚会中见到他的直接上 ...
随机推荐
- 分享使用method swizzling的经历
原文:http://www.cnblogs.com/lujianwenance/p/5800232.html 这是一个很蛋疼的过程,先说一下需求,列表页预加载更多(60%).当我看到这个需求的时候 ...
- Object-C Dealloc
上一篇为Object-C Init dealloc方法在一个对象从内存中删除时被调用.通常在这个方法里面释放所有对象里的实例变量 -(void)dealloc { [super dealloc]; [ ...
- PIMP模式的理解
看了[C++程序设计技巧]Pimpl机制 之后,想了半天才理解 // MyClass.h 2: class MyClassImpl; // forward declaration 3: clas ...
- javax.el.PropertyNotFoundException: Property 'aDesc' not found on type
这个问题是是在我使用jeesite自动代码是产生的,原因是实体类的属性命名规范不合格,我在网上看到类的属性前三个字母不能出现大写 解决办法:将类的属性大小写改一下
- HDU 3555 Bomb (数位DP)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3555 题目大意:从0开始到给定的数字N所有的数字中遇到“49”的数字的个数. Sample Input ...
- RD / RMDIR Command
Quote from: http://ss64.com/nt/rd.html RD Delete folder(s) Syntax RD pathname RD /S pathname RD /S / ...
- Java基础巩固--正则表达式
本篇文章是学习尚学堂的关于正则表达式的视频教程时,所做的笔记.供广大编程爱好者学习之用,也留给日后自己复习使用! 1.为什么要有正则表达式? 正则表达式可以方便的对数据进行匹配,可以进行更加复杂的字符 ...
- std::string stringf(const char* format, ...)
std::string stringf(const char* format, ...){ va_list arg_list; va_start(arg_list, format); // SUSv2 ...
- make makefile
Gcc的编译流程预处理阶段: gcc –E hello.c –o hello.i编译阶段: gcc –S hello.i –o hello.s汇编阶段:gcc –c hello.s –o hello. ...
- Cocos2d-x课程大纲/学习路线
Cocos2d-x课程大纲/学习路线 这是什么? 这个一个Cocos2d-x技术路线的课程大纲/学习大纲. 你能用它做什么? 如果你是找工作的人, 利用本大纲, 你可以学习Cocos2d-x, 做一个 ...