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个灯泡不需要 ...
随机推荐
- 关于vs2015无法启动iis服务
关于vs2015无法启动iis服务,以下是我自己从网上找到的问题的几种解决办法 1.安装Visual Sutudil 2015 Update 3后调试项目出现问题“无法启动iis express we ...
- WCF-终结点之消息路由示例
一. 在前一章中主要介绍了服务端的监听地址与逻辑地址.本节模拟消息转发机制来实际体验一把终结点的监听地址是如何使用的. 先下载一个叫做TcpTrace的小软件(108k),它能够截取端口消息,并转发消 ...
- Azure .NET Libraries 入门
本指南演示了以下 Azure .NET API 的用法,包括设置认证.创建并使用 Azure 存储.创建并使用 Azure SQL 数据库.部署虚拟机.从 GitHub 部署 Azure Web 应用 ...
- Java开发学习--Java 中基本类型和包装类之间的转换
Java 中基本类型和包装类之间的转换 基本类型和包装类之间经常需要互相转换,以 Integer 为例(其他几个包装类的操作雷同哦): 在 JDK1.5 引入自动装箱和拆箱的机制后,包装类和基本类型之 ...
- 多线程-lock锁
package 多线程.lock锁; import java.util.concurrent.locks.ReentrantLock; /*. * * //同步代码块 * * */ public cl ...
- C#操作xml文件:使用XmlDocument 实现读取和写入
XML文件是一种常用的文件格式,例如WinForm里面的app.config以及Web程序中的web.config文件,还有许多重要的场所都有它的身影.Xml是Internet环境中跨平台的,依赖于内 ...
- Java基础之java的四大特性
上篇文章说了jdk的安装和java环境的配置,这篇文章主要说下java的特性. 首相说下,编程语言分为面向过程和面向对象,而java就是一种面向对象的编程语言. 什么是面向过程编程呢?就是一流程为单位 ...
- Hibernate入门(三)—— 一对多、多对多关系
一.一对多关系 1.概念 一对多关系是关系型数据库中两个表之间的一种关系.通常在数据库层级中,两表之间是有主外键关系的.在ORM中,如何通过对象描述表之间的关系,是ORM核心. 2.Hiberna ...
- Redis实现分布式锁2
redisTemplate实现分布式锁 /** * 分布式锁-加锁 * @param key * @param value 当前时间+超时时间 System.currentTimeMillis()+t ...
- CSS选择器:#id和.class中间有空格和无空格的区别
相信大家都知道 .class1 .class2 和 .class1.class2 是两种不同的选择规则,但具体怎样不同呢? 首先中间有空格的情况:是选择到.class1类下的.class2类子节点,即 ...