Description

小凸和小方相约玩密室逃脱,这个密室是一棵有n个节点的完全二叉树,每个节点有一个灯泡。点亮所有灯泡即可逃出密室。
每个灯泡有个权值Ai,每条边也有个权值bi。点亮第1个灯泡不需要花费,之后每点亮1个新的灯泡V的花费,等于上一个被点亮的灯泡U到这个点V的距离Du,v,乘以这个点的权值Av。
在点灯的过程中,要保证任意时刻所有被点亮的灯泡必须连通,在点亮一个灯泡后必须先点亮其子树所有灯泡才能点亮其他灯泡。
请告诉他们,逃出密室的最少花费是多少。

Input

第1行包含1个数n,代表节点的个数
第2行包含n个数,代表每个节点的权值ai。(i=1,2,…,n)
第3行包含n-l个数,代表每条边的权值bi,第i号边是由第(i+1)/2号点连向第i+l号点的边。(i=1,2...N-1)

Output

输出包含1个数,代表最少的花费。

Sample Input

3
5 1 2
2 1

Sample Output

5

HINT

对于100%的数据,1≤N≤2×10^5,1<Ai,Bi≤10^5

Solution

神仙树形DP

一条合法的行走路径,一定是先走完一个点的子树,再访问它的兄弟的子树,访问完了就回到父节点。以此类推。

也就是说要求从某个点出发,访问完其子树后回到某个祖先的最小代价。

设$f[x][i]$表示从$x$开始访问完$x$的子树后再走到深度为$i$的祖先(设为$kfa$)的最小代价。

设$g[x][i]$表示从$x$开始访问完$x$的子树后再走到深度为$i$的祖先的另外一个儿子的最小代价。

$DP$完了之后枚举最开始先点亮哪个灯然后统计答案。因为是完全二叉树所以时空都是$nlogn$

转移见代码,手画个图对比着理解效果应该会好一点……

Code

 #include<iostream>
#include<cstdio>
#define N (200009)
#define LL long long
#define ls (i<<1)
#define rs (i<<1|1)
#define kfa (i>>Depth[i]-j)
using namespace std; LL n,Depth[N],Dist[N],a[N],b[N],g[N][],f[N][],ans=1e18; void DP()
{
for (int i=n; i>=; --i)
for (int j=; j<=Depth[i]; ++j)
if (ls>n)//当前是叶子
{
f[i][j]=(Dist[i]-Dist[kfa])*a[kfa];
g[i][j]=(Dist[i]-Dist[kfa]+b[kfa]+b[kfa^])*a[kfa^];
}
else if (ls==n)//只有左儿子
{
f[i][j]=b[ls]*a[ls]+f[ls][j];
g[i][j]=b[ls]*a[ls]+g[ls][j];
}
else//左右儿子都有
{
f[i][j]=min(
b[ls]*a[ls]+g[ls][Depth[ls]]+f[rs][j],
b[rs]*a[rs]+g[rs][Depth[rs]]+f[ls][j]);
g[i][j]=min(
b[ls]*a[ls]+g[ls][Depth[ls]]+g[rs][j],
b[rs]*a[rs]+g[rs][Depth[rs]]+g[ls][j]);
}
} int main()
{
scanf("%lld",&n);
for (int i=; i<=n; ++i)
scanf("%lld",&a[i]);
for (int i=; i<=n; ++i)
scanf("%lld",&b[i]);
for (int i=; i<=n; ++i)
{
Depth[i]=Depth[i>>]+;
Dist[i]=Dist[i>>]+b[i];
}
DP();
for (int i=; i<=n; ++i)//枚举最先点哪个灯统计答案
{
LL now=f[i][Depth[i]-];
for (int j=i; j!=; j>>=)
if ((j^)>n) now+=b[j>>]*a[j>>];
else now+=b[j^]*a[j^]+f[j^][Depth[j]-];
ans=min(ans,now);
}
printf("%lld\n",ans);
}

BZOJ4446:[SCOI2015]小凸玩密室(树形DP)的更多相关文章

  1. [BZOJ4446]SCoi2015 小凸玩密室 树形DP(烧脑高能预警)

    4446: [Scoi2015]小凸玩密室 Time Limit: 10 Sec  Memory Limit: 128 MB Description 小凸和小方相约玩密室逃脱,这个密室是一棵有n个节点 ...

  2. LUOGU P4253 [SCOI2015]小凸玩密室(树形dp)

    传送门 解题思路 玄学树形\(dp\),题目描述极其混乱...看错了两次题,设首先根据每次必须点完子树里的灯才能点别的,那么点灯情况只有两种,第一种是点到某一个祖先,第二种是点到某一个祖先的兄弟.所以 ...

  3. BZOJ.4446.[SCOI2015]小凸玩密室(树形DP)

    BZOJ LOJ 洛谷 (下面点亮一个灯泡就说成染色了,感觉染色比较顺口... 注意完全二叉树\(\neq\)满二叉树,点亮第一个灯泡\(\neq\)第一次点亮一号灯泡,根节点应该就是\(1\)... ...

  4. BZOJ4446 [Scoi2015]小凸玩密室 【树形Dp】

    题目 小凸和小方相约玩密室逃脱,这个密室是一棵有n个节点的完全二叉树,每个节点有一个灯泡.点亮所有灯 泡即可逃出密室.每个灯泡有个权值Ai,每条边也有个权值bi.点亮第1个灯泡不需要花费,之后每点亮4 ...

  5. 2019.03.26 bzoj4446: [Scoi2015]小凸玩密室(树形dp)

    传送门 题意简述: 给一棵完全二叉树,有点权aia_iai​和边权,每个点有一盏灯,现在要按一定要求点亮: 任意时刻点亮的灯泡必须连通 点亮一个灯泡后必须先点亮其子树 费用计算如下:点第一盏灯不要花费 ...

  6. BZOJ4446 SCOI2015小凸玩密室(树形dp)

    设f[i][j]为由根进入遍历完i子树,最后一个到达的点是j时的最小代价,g[i][j]为由子树内任意一点开始遍历完i子树,最后一个到达的点是j时的最小代价,因为是一棵完全二叉树,状态数量是nlogn ...

  7. BZOJ4446: [Scoi2015]小凸玩密室

    用ui,j表示走完i的子树后走到i的深度为j的祖先的兄弟的最小代价: 用vi,j表示走完i的子树后走到i的深度为j的祖先的最小代价,用u算出v. 枚举起点,计算答案. #include<bits ...

  8. [bzoj4446] [loj#2009] [Scoi2015] 小凸玩密室

    Description 小凸和小方相约玩密室逃脱,这个密室是一棵有 \(n\) 个节点的完全二叉树,每个节点有一个灯泡.点亮所有灯泡即可逃出密室.每个灯泡有个权值 \(Ai\) ,每条边也有个权值 \ ...

  9. bzoj 4446: [Scoi2015]小凸玩密室

    Description 小凸和小方相约玩密室逃脱,这个密室是一棵有n个节点的完全二叉树,每个节点有一个灯泡.点亮所有灯 泡即可逃出密室.每个灯泡有个权值Ai,每条边也有个权值bi.点亮第1个灯泡不需要 ...

随机推荐

  1. JavaScript ES6 Symbol.hasInstance的理解。

    Symbol.hasInstance 本案例是结合阮一峰老师的ECMAScript 6 入门丛书进一步的详细介绍,和对Symbol.hasInstance的理解.本着互联网的精神,分享给大家. 对象的 ...

  2. DateGridView 分页显示

    l 思路:将数据表整体填充至一个Dataset中,探后部分显示(DataaAdapter Fill重载) l DataGridView 控件   l BindingNavigator 控件   l B ...

  3. Q:java中的泛型数组

     对于java,其是不支持直接创建泛型数组的.当采用如下的方式去创建一个泛型数组时,其会出现错误,编译无法通过的情况. package other.jdk1_5; /** * 该类用于演示泛型数组的创 ...

  4. Oracle数据库基本操作 (五) —— 使用java调用存储过程

    一.环境准备 登录Oracle数据库scott账号,利用emp进行操作. 1.创建 proc_getyearsal 存储过程 -- 获取指定员工年薪 create or replace procedu ...

  5. CNN中卷积过程中padding的使用

    1.podding='SAME'时,全0填充.     2.padding=“VALID”,不使用全0填充      

  6. 【转】怎么用PHP发送HTTP请求(POST请求、GET请求)?

    file_get_contents版本: /** * 发送post请求 * @param string $url 请求地址 * @param array $post_data post键值对数据 * ...

  7. 第8课 网络数据读取测试-TinyWebDB

    TinyWebDB是在线小型数据库,通过它的使用,可以将数据保存在网络,实现排行榜等功能.   实现功能:读入数据并保存,读出数据并显示.   1.组件设计   TinyWebDB1:非可视化,借用网 ...

  8. C语言指针数组(每个元素都是指针)

    转载:http://c.biancheng.net/cpp/html/3246.html 注意:数组指针的区别 如果一个数组中的所有元素保存的都是指针,那么我们就称它为指针数组.指针数组的定义形式一般 ...

  9. 学习使用PRINCE2能带来什么益处?

    使用PRINCE2有许多好处.它除了可重复使用.可升级.非常灵活之外,是在成百上千名有经验的项目经理们的帮助下,总结他们多年积累的实践经验和专业技术建立的. PRINCE2 开发于1989年并从此不断 ...

  10. 算法之水仙花数(Java语言)

    概述 在数论中,水仙花数(Narcissistic number),也被称为超完全数字不变数(pluperfect digital invariant, PPDI).自恋数.自幂数.阿姆斯壮数或阿姆斯 ...