BZOJ4446 [Scoi2015]小凸玩密室 【树形Dp】
题目
小凸和小方相约玩密室逃脱,这个密室是一棵有n个节点的完全二叉树,每个节点有一个灯泡。点亮所有灯
泡即可逃出密室。每个灯泡有个权值Ai,每条边也有个权值bi。点亮第1个灯泡不需要花费,之后每点亮4
个新的灯泡V的花费,等于上一个被点亮的灯泡U到这个点V的距离Du,v,乘以这个点的权值Av。在点灯
的过程中,要保证任意时刻所有被点亮的灯泡必须连通,在点亮一个灯泡后必须先点亮其子树所有灯泡才能点亮其他灯泡。请告诉他们,逃出密室的最少花费是多少。
输入格式
第1行包含1个数n,代表节点的个数
第2行包含n个数,代表每个节点的权值ai。(i=l,2,…,n)
第3行包含n-l个数,代表每条边的权值bi,第i号边是由第(i+1)/2号点连向第i+l号点的边。
(i=l,2...N-1)
输出格式
输出包含1个数,代表最少的花费。
输入样例
3
5 1 2
2 1
输出样例
5
提示
对于100%的数据,1≤N≤2×105,1<Ai,Bi≤10^5
题解
首先,此题有一些比较重要的性质:
①这棵树是一棵完全二叉树
②每次要处理完一个子树才能往祖先节点处理
③所有时刻点亮的点必须联通
④初始可以从任意点开始点亮
由这些性质,我们会发现从一个节点出发,整棵树被点亮的顺序是比较固定的,
点亮一个点u,然后点亮其子树
然后再点亮u的父亲,然后点亮u的兄弟的子树
然后点亮u父亲的父亲,点亮u父亲的父亲的兄弟的子树

像这样
设\(g[i][j]\)表示从\(i\)节点开始,点亮\(i\)所在子树,然后点亮\(i\)位于第\(j\)层的祖先的最小费用
如果我们知道\(g[i][j]\),就可以枚举出发点,然后模拟上图的过程算出最后的代价
现在问题转化为如何求\(g[i][j]\)
考虑树形dp的模式
对于节点u,我们想要求出\(g[u][j]\)
①u为叶子节点,直接计算到\(j\)层祖先的价值,如果该祖先为v,则\(g[u][j] = (d[u] - d[v])*a[v]\)【d[u]指到根距离】
②u只有一个儿子,记为s,当然是\(g[u][j] = b[s] * a[s] + g[s][j]\)
③u有两个儿子
此时有两种选择:
1°先走左子树,然后走到右子树,再走到\(j\)层的父亲
2°先走右子树,然后走到左子树,再走到\(j\)层的父亲
对于两种选择,我们求出最小者
诶?等等,走到父亲的花费就是\(g\),但走到兄弟的花费呢?
我们记\(f[i][j]\)表示从节点\(i\)访问其子树并走到第\(j\)层的兄弟的最小花费
那么这两种选择就可以写成:
\(min(b[ls] * a[ls] + f[ls][dep[rs]] + g[rs][j],
b[rs] * a[rs] + f[rs][dep[ls]] + g[ls][j])\)
现在问题就转化成了求\(f[i][j]\)
用同样的思想,我们对节点u有:
①如果u为叶子节点,可以直接求出其\(f[i][j] = dis * a[v]\)
②如果u只有一个儿子,记为s,\(f[i][j] = b[s] * a[s] + f[s][j]\)
③u有两个儿子,
同样有两种类似的选择
\(min(b[ls] * a[ls] + f[ls][dep[rs]] + f[rs][j],
b[rs] * a[rs] + f[rs][dep[ls]] + f[ls][j])\)
那么这样,这题我们就做完啦
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#define LL long long int
#define REP(i,n) for (int i = 1; i <= (n); i++)
#define Redge(u) for (int k = h[u]; k; k = ed[k].nxt)
using namespace std;
const int maxn = 200005,maxm = 100005,INF = 1000000000;
inline int read(){
int out = 0,flag = 1; char c = getchar();
while (c < 48 || c > 57) {if (c == '-') flag = -1; c = getchar();}
while (c >= 48 && c <= 57) {out = (out << 1) + (out << 3) + c - '0'; c = getchar();}
return out * flag;
}
LL g[maxn][20],f[maxn][20];
LL n,a[maxn],b[maxn],d[maxn],dep[maxn];
void cal(){
for (int i = n; i; i--){
int ls = i << 1,rs = i << 1 | 1;
for (int j = dep[i]; j; j--){
int s = (i >> (dep[i] - j)) ^ 1,fa = s >> 1;
if (ls > n) f[i][j] = (d[i] - d[fa] + b[s]) * a[s];
else if (rs > n) f[i][j] = a[ls] * b[ls] + f[ls][j];
else f[i][j] = min(
a[ls] * b[ls] + f[ls][dep[ls]] + f[rs][j],
a[rs] * b[rs] + f[rs][dep[rs]] + f[ls][j]
);
}
}
for (int i = n; i; i--){
int ls = i << 1,rs = i << 1 | 1;
if (ls > n) g[i][0] = 0;
else if (rs > n) g[i][0] = a[ls] * b[ls] + g[ls][0];
else g[i][0] = min(
a[ls] * b[ls] + f[ls][dep[ls]] + g[rs][0],
a[rs] * b[rs] + f[rs][dep[rs]] + g[ls][0]
);
for (int j = dep[i] - 1; j; j--){
int fa = (i >> (dep[i] - j));
if (ls > n) g[i][j] = (d[i] - d[fa]) * a[fa];
else if (rs > n) g[i][j] = a[ls] * b[ls] + g[ls][j];
else g[i][j] = min(
a[ls] * b[ls] + f[ls][dep[ls]] + g[rs][j],
a[rs] * b[rs] + f[rs][dep[rs]] + g[ls][j]
);
}
}
}
void solve(){
LL ans = g[1][0];
for (int i = 2; i <= n; i++){
LL cost = g[i][dep[i] - 1];
int x,fa;
for (int u = i; u > 1; u >>= 1){
x = u ^ 1; fa = u >> 1;
if (x > n) cost += b[fa] * a[fa >> 1];
else cost += a[x] * b[x] + g[x][dep[fa] - 1];
}
ans = min(ans,cost);
}
printf("%lld\n",ans);
}
int main(){
n = read();
for (int i = 1; i <= n; i++) a[i] = read();
for (int i = 2; i <= n; i++) b[i] = read();
dep[1] = 1;
for (int i = 1; i <= n; i++){
if ((i << 1) <= n){
dep[i << 1] = dep[i] + 1;
d[i << 1] = d[i] + b[i << 1];
}
if ((i << 1 | 1) <= n){
dep[i << 1 | 1] = dep[i] + 1;
d[i << 1 | 1] = d[i] + b[i << 1 | 1];
}
}
cal();
solve();
return 0;
}
BZOJ4446 [Scoi2015]小凸玩密室 【树形Dp】的更多相关文章
- [BZOJ4446]SCoi2015 小凸玩密室 树形DP(烧脑高能预警)
4446: [Scoi2015]小凸玩密室 Time Limit: 10 Sec Memory Limit: 128 MB Description 小凸和小方相约玩密室逃脱,这个密室是一棵有n个节点 ...
- BZOJ4446:[SCOI2015]小凸玩密室(树形DP)
Description 小凸和小方相约玩密室逃脱,这个密室是一棵有n个节点的完全二叉树,每个节点有一个灯泡.点亮所有灯泡即可逃出密室. 每个灯泡有个权值Ai,每条边也有个权值bi.点亮第1个灯泡不需要 ...
- LUOGU P4253 [SCOI2015]小凸玩密室(树形dp)
传送门 解题思路 玄学树形\(dp\),题目描述极其混乱...看错了两次题,设首先根据每次必须点完子树里的灯才能点别的,那么点灯情况只有两种,第一种是点到某一个祖先,第二种是点到某一个祖先的兄弟.所以 ...
- BZOJ.4446.[SCOI2015]小凸玩密室(树形DP)
BZOJ LOJ 洛谷 (下面点亮一个灯泡就说成染色了,感觉染色比较顺口... 注意完全二叉树\(\neq\)满二叉树,点亮第一个灯泡\(\neq\)第一次点亮一号灯泡,根节点应该就是\(1\)... ...
- 2019.03.26 bzoj4446: [Scoi2015]小凸玩密室(树形dp)
传送门 题意简述: 给一棵完全二叉树,有点权aia_iai和边权,每个点有一盏灯,现在要按一定要求点亮: 任意时刻点亮的灯泡必须连通 点亮一个灯泡后必须先点亮其子树 费用计算如下:点第一盏灯不要花费 ...
- BZOJ4446 SCOI2015小凸玩密室(树形dp)
设f[i][j]为由根进入遍历完i子树,最后一个到达的点是j时的最小代价,g[i][j]为由子树内任意一点开始遍历完i子树,最后一个到达的点是j时的最小代价,因为是一棵完全二叉树,状态数量是nlogn ...
- BZOJ4446: [Scoi2015]小凸玩密室
用ui,j表示走完i的子树后走到i的深度为j的祖先的兄弟的最小代价: 用vi,j表示走完i的子树后走到i的深度为j的祖先的最小代价,用u算出v. 枚举起点,计算答案. #include<bits ...
- [bzoj4446] [loj#2009] [Scoi2015] 小凸玩密室
Description 小凸和小方相约玩密室逃脱,这个密室是一棵有 \(n\) 个节点的完全二叉树,每个节点有一个灯泡.点亮所有灯泡即可逃出密室.每个灯泡有个权值 \(Ai\) ,每条边也有个权值 \ ...
- bzoj 4446: [Scoi2015]小凸玩密室
Description 小凸和小方相约玩密室逃脱,这个密室是一棵有n个节点的完全二叉树,每个节点有一个灯泡.点亮所有灯 泡即可逃出密室.每个灯泡有个权值Ai,每条边也有个权值bi.点亮第1个灯泡不需要 ...
随机推荐
- MySQL常用函数使用示例
#从指定字符中,随机生成12位字符select substring('0123456789abcdefghijklmnopqrstuvwxyz',floor(0+RAND()*36),12); #显示 ...
- get和post请求及进程和线程及cookie和session的区别
get和post请求及进程和线程及cookie和session的区别 1.get和post请求的区别 get请求是指向服务器进行获取查询数据的请求,post请求指向服务器提交数据的请求. get请求如 ...
- POJ 1655 Balancing Act (树的重心,常规)
题意:求树的重心,若有多个重心,则输出编号较小者,及其子树中节点最多的数量. 思路: 树的重心:指的是一个点v,在删除点v后,其子树的节点数分别为:u1,u2....,设max(u)为其中的最大值,点 ...
- Oracle错误(包括PL/SQL)集合与修复
+-----------------------------------------------------------------------+ | 在本篇随笔中,仅根据个人经验累积错误进行描述 ...
- 爆零系列—补题A
http://codeforces.com/contest/615/problem/A 读错题 结果发现是无脑题 直接标记统计 #include<cstdio> #include< ...
- 转向ARC的说明
转自hherima的博客原文:Transitioning to ARC Release Notes(苹果官方文档) ARC是一个编译器特征,它提供了对OC对象自动管理内存.ARC让开发者专注于感兴趣的 ...
- mybatis 原理研究
1. mybatis 是使用JDBC来实现的, 所以需要我们首先了解JDBC 的查询 ①加载JDBC驱动 ②建立并获取数据库连接 ③设置sql语句的传递参数 ④执行sql语句并获得结果 ⑤对结果进行转 ...
- Bootstrap 网格系统(Grid System)实例2
Bootstrap 网格系统(Grid System):堆叠水平,两种样式 <!DOCTYPE html><html><head><meta http-equ ...
- GIMP模板选区操作
选择方法有很多种,这里我就新学的方法记录一下,主要是通过小剪刀和Toggle Quick Mask 相结合的运用. 选择Scissors Select Tool工具 设置基本的属性:Antialisa ...
- Web框架之Django_02基本操作(Django项目启动配置、数据库连接、orm、增删改查)
摘要: Django项目简单现实过程 pycharm连接数据库 Django之orm简单操作增删改查 一.新建Django项目.配置.设置: 新建Django项目:(为了熟悉Django操作,暂时全部 ...