BZOJ4446:[SCOI2015]小凸玩密室(树形DP)
Description
Input
Output
Sample Input
5 1 2
2 1
Sample Output
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)的更多相关文章
- [BZOJ4446]SCoi2015 小凸玩密室 树形DP(烧脑高能预警)
4446: [Scoi2015]小凸玩密室 Time Limit: 10 Sec Memory Limit: 128 MB Description 小凸和小方相约玩密室逃脱,这个密室是一棵有n个节点 ...
- LUOGU P4253 [SCOI2015]小凸玩密室(树形dp)
传送门 解题思路 玄学树形\(dp\),题目描述极其混乱...看错了两次题,设首先根据每次必须点完子树里的灯才能点别的,那么点灯情况只有两种,第一种是点到某一个祖先,第二种是点到某一个祖先的兄弟.所以 ...
- BZOJ.4446.[SCOI2015]小凸玩密室(树形DP)
BZOJ LOJ 洛谷 (下面点亮一个灯泡就说成染色了,感觉染色比较顺口... 注意完全二叉树\(\neq\)满二叉树,点亮第一个灯泡\(\neq\)第一次点亮一号灯泡,根节点应该就是\(1\)... ...
- BZOJ4446 [Scoi2015]小凸玩密室 【树形Dp】
题目 小凸和小方相约玩密室逃脱,这个密室是一棵有n个节点的完全二叉树,每个节点有一个灯泡.点亮所有灯 泡即可逃出密室.每个灯泡有个权值Ai,每条边也有个权值bi.点亮第1个灯泡不需要花费,之后每点亮4 ...
- 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个灯泡不需要 ...
随机推荐
- JavaScript ES6 Symbol.hasInstance的理解。
Symbol.hasInstance 本案例是结合阮一峰老师的ECMAScript 6 入门丛书进一步的详细介绍,和对Symbol.hasInstance的理解.本着互联网的精神,分享给大家. 对象的 ...
- DateGridView 分页显示
l 思路:将数据表整体填充至一个Dataset中,探后部分显示(DataaAdapter Fill重载) l DataGridView 控件 l BindingNavigator 控件 l B ...
- Q:java中的泛型数组
对于java,其是不支持直接创建泛型数组的.当采用如下的方式去创建一个泛型数组时,其会出现错误,编译无法通过的情况. package other.jdk1_5; /** * 该类用于演示泛型数组的创 ...
- Oracle数据库基本操作 (五) —— 使用java调用存储过程
一.环境准备 登录Oracle数据库scott账号,利用emp进行操作. 1.创建 proc_getyearsal 存储过程 -- 获取指定员工年薪 create or replace procedu ...
- CNN中卷积过程中padding的使用
1.podding='SAME'时,全0填充. 2.padding=“VALID”,不使用全0填充
- 【转】怎么用PHP发送HTTP请求(POST请求、GET请求)?
file_get_contents版本: /** * 发送post请求 * @param string $url 请求地址 * @param array $post_data post键值对数据 * ...
- 第8课 网络数据读取测试-TinyWebDB
TinyWebDB是在线小型数据库,通过它的使用,可以将数据保存在网络,实现排行榜等功能. 实现功能:读入数据并保存,读出数据并显示. 1.组件设计 TinyWebDB1:非可视化,借用网 ...
- C语言指针数组(每个元素都是指针)
转载:http://c.biancheng.net/cpp/html/3246.html 注意:数组指针的区别 如果一个数组中的所有元素保存的都是指针,那么我们就称它为指针数组.指针数组的定义形式一般 ...
- 学习使用PRINCE2能带来什么益处?
使用PRINCE2有许多好处.它除了可重复使用.可升级.非常灵活之外,是在成百上千名有经验的项目经理们的帮助下,总结他们多年积累的实践经验和专业技术建立的. PRINCE2 开发于1989年并从此不断 ...
- 算法之水仙花数(Java语言)
概述 在数论中,水仙花数(Narcissistic number),也被称为超完全数字不变数(pluperfect digital invariant, PPDI).自恋数.自幂数.阿姆斯壮数或阿姆斯 ...