[HNOI2018] 道路
Description
给一棵二叉树,每个叶子节点 \(i\) 有三个属性 \(a_i,b_i,c_i\)
每个非叶子节点都能标记向左右儿子中的一条边(记作 \(x\) 边和 \(y\) 边)
设叶子节点 \(i\) 到根的路径上有 \(p\) 条没被标记的 \(x\) 边,\(q\) 条没被标记的 \(y\) 边
那么 \(i\) 的花费就是 \(c_i\times (a_i+p)\times (b_i+q)\)
最小化这个花费
Solution
传说中的pj难度题
这个式子有点吓人啊
定义 \(f[i][j][k]\) 表示 \(i\) 到根的路径上,有 \(j\) 条没被标记的 \(x\) 边, \(k\) 条没被标记的 \(y\) 边 \(i\) 的最小花费
对于叶子节点,直接枚举 \(x\) 和 \(y\) 边各有多少条
对于非叶节点,左右儿子选择一条标记取最小值就行了
等等,我们来算一下空间复杂度
第一维要开 \(2n\),第二第三维至少要开 \(41\),又因为答案会爆 \(int\),所以要开 \(long\;long\)
那么光 \(f\) 数组的空间占用就是 \(40010*1600*8/1024/1024 \approx 488M\),显然不够用
我们考虑二叉树的性质,一个点的 \(f\) 值只用知道它的左右儿子的 \(f\) 值即可,又因为最多只有 \(\log n\) 层,所以我们动态分配内存,这样下来空间复杂度就是 \(O(\log n*1600)\) 了。
Code
#include<cstdio>
#include<cctype>
#include<cstring>
#define N 20005
#define in inline
typedef long long ll;
#define re register signed
#define min(A,B) ((A)<(B)?(A):(B))
#define max(A,B) ((A)>(B)?(A):(B))
#define swap(A,B) ((A)^=(B)^=(A)^=(B))
//一颗二叉树 f[i][j][k]->refers from 1 to i,still has j highway,k railway,mininum cost
int n,cnt;
int ch[N][2];
int stk[N],top;
ll f[100][45][45];
int a[N],b[N],c[N];
int hi[N<<1],ri[N<<1];
//要压空间 sb题
//开栈 最多logn
in int getint(){
int x=0,f=0;char ch=getchar();
while(!isdigit(ch)) f|=ch=='-',ch=getchar();
while(isdigit(ch)) x=(x<<1)+(x<<3)+(ch^48),ch=getchar();
return f?-x:x;
}
in int newnode(){
return top?stk[top--]:++cnt;
}
void dp(int now,int d,int k){
if(now>n){
for(int i=0;i<=hi[now];i++){
for(int j=0;j<=ri[now];j++)
f[k][i][j]=(ll)c[now-n]*(a[now-n]+i)*(b[now-n]+j);
}
return;
}
int x=newnode();
int y=newnode();
dp(ch[now][0],0,x);
dp(ch[now][1],1,y);
for(re i=0;i<=hi[now];i++){
for(re j=0;j<=ri[now];j++)
f[k][i][j]=min(f[x][i][j]+f[y][i][j+1],f[x][i+1][j]+f[y][i][j]);
}
stk[++top]=x;stk[++top]=y;
/* puts("");
printf("now=%d\n",now);
for(int i=0;i<=hi[now];i++){
for(int j=0;j<=ri[now];j++)
printf("i=%d,j=%d,f=%lld\n",i,j,f[k][i][j]);
}*/
}
void dfs(int now,int x,int y){
if(now>n){hi[now]=x;ri[now]=y;return;}
if(ch[now][0]) dfs(ch[now][0],x+1,y);
if(ch[now][1]) dfs(ch[now][1],x,y+1);
hi[now]=x;ri[now]=y;
}
signed main(){
n=getint();
for(re i=1;i<n;i++){
int x=getint(),y=getint();
if(x<0) x=n-x;
if(y<0) y=n-y;
ch[i][0]=x;ch[i][1]=y; //leftson->highway rightson->railway
}
for(re i=1;i<=n;i++)
a[i]=getint(),b[i]=getint(),c[i]=getint();
dfs(1,0,0);
int x=newnode();
dp(1,0,x);
printf("%lld\n",f[x][0][0]);
return 0;
}
[HNOI2018] 道路的更多相关文章
- 【BZOJ5290】 [Hnoi2018]道路
BZOJ5290 [Hnoi2018]道路 前言 这道题目我竟然没有在去年省选切? 我太菜了. Solution 对题面进行一个语文透彻解析,发现这是一个二叉树,乡村都是叶子节点,城市都有两个儿子.( ...
- 5290: [Hnoi2018]道路
5290: [Hnoi2018]道路 链接 分析: 注意题目中说每个城市翻新一条连向它的公路或者铁路,所以两种情况分别转移一下即可. 注意压一下空间,最后的叶子节点不要要访问,空间少了一半. 代码: ...
- [HNOI2018]道路 --- 树形DP
[HNOI2018]道路 题目描述: W 国的交通呈一棵树的形状.W 国一共有 \(n-1\) 个城市和 \(n\) 个乡村, 其中城市从 \(1\) 到 \(n-1\) 编号,乡村从 \(1\) 到 ...
- 【BZOJ5290】[HNOI2018]道路(动态规划)
[BZOJ5290][HNOI2018]道路(动态规划) 题面 BZOJ 洛谷 题目直接到洛谷上看吧 题解 开始写写今年省选的题目 考场上我写了一个模拟退火骗了\(90\)分...然而重测后只剩下45 ...
- bzoj 5290: [Hnoi2018]道路
Description Solution PJDP毁青春 注意到性质:到根的道路不超过 \(40\) 条 所以我们只关系一个点上面的道路的情况就行了 设 \(f[x][i][j]\) 表示一个点 \( ...
- [HNOI2018]道路(DP)
题目描述 W 国的交通呈一棵树的形状.W 国一共有n−1n - 1n−1 个城市和nnn 个乡村,其中城市从111 到n−1n - 1n−1 编号,乡村从111 到nnn 编号,且111 号城市是首都 ...
- 洛谷4438 [Hnoi2018]道路 【树形dp】
题目 题目太长懒得打 题解 HNOI2018惊现普及+/提高? 由最长路径很短,设\(f[i][x][y]\)表示\(i\)号点到根有\(x\)条未修公路,\(y\)条未修铁路,子树所有乡村不便利值的 ...
- [洛谷P4438] HNOI2018 道路
问题描述 W 国的交通呈一棵树的形状.W 国一共有n - 1个城市和n个乡村,其中城市从1到n - 1 编号,乡村从1到n编号,且1号城市是首都.道路都是单向的,本题中我们只考虑从乡村通往首都的道路网 ...
- BZOJ.5290.[AHOI/HNOI2018]道路(树形DP)
BZOJ LOJ 洛谷 老年退役选手,都写不出普及提高DP= = 在儿子那统计贡献,不是在父亲那统计啊!!!(这样的话不写这个提高DP写记忆化都能过= =) 然后就令\(f[x][a][b]\)表示在 ...
随机推荐
- linux命令重定向>、>>、 1>、 2>、 1>>、 2>>、 <
重定向命令其实用得不少吧,只是重来都没有仔细看过,这波正好又用到 又有空总结一波. 先看>和>>: 他们俩其实唯一的区别就是>是重定向到一个文件,>>是追加内容到文 ...
- 【git】仓库目录下文件不加入版本控制
如果文件未做过提交操作,在文件所在目录或上级目录新建.gitignore文本文件,将文件的相对路径写入,再将该文本文件提交,则目标文件将被git忽略. 补一个gitignore文件书写规范 2.至于已 ...
- Android 软件管理工具类Utils
Android 软件管理工具类Utils /** * Created by uilubo on 2015/9/30. * 工具类 */ public class Utils { public stat ...
- poj3130 (半平面交
题意:判断是否存在内核. 半平面交存板子. /* gyt Live up to every day */ #include<cstdio> #include<cmath> #i ...
- html样式板
一.bootstrap 二.element 三.iconfont图标 四.font awesome图标
- s5 Docker的持久化存储和数据共享
数据库容器的数据如何才能不会丢失?Docker的持久化存储技术.Docker的数据共享技术能极大提高开发人员的开发效率,边写代码,边看运行结果. 数据持久化之Data Volume Docker持久化 ...
- 源码解读Linux的limits.conf文件
目录 目录 1 1. 前言 1 2. PAM 2 3. pam_limits 2 4. limits.conf的由来 3 5. 模块入口函数 4 6. 解析limits.conf 6 7. 生效lim ...
- 前端基于easyui的mvc扩展
背景 由于MVC的前端是基于jquery.validate和jquery.validate.unobtrusive来实现的,但是当我们要使用其他的ui组件且组件本身就带有完整的验证功能的话,那么要让它 ...
- Alpha冲刺-(9/10)
Part.1 开篇 队名:彳艮彳亍团队 组长博客:戳我进入 作业博客:班级博客本次作业的链接 Part.2 成员汇报 组员1(组长)柯奇豪 过去两天完成了哪些任务 进一步优化代码,结合自己负责的部分修 ...
- RxSwift学习笔记8:filter/distinctUntilChanged/single/elementAt/ignoreElements/take/takeLast/skip/sample/debounce
//filter:该操作符就是用来过滤掉某些不符合要求的事件. Observable.of(1,2,3,4,5,8).filter({ $0 % 2 == 0 }).subscribe { (even ...