[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]\)表示在 ...
随机推荐
- Java:foreach实现原理
第一部分: For-each Loop Purpose The basic for loop was extended in Java5 to make iteration over arrays a ...
- hdu-1878(欧拉回路)
题目链接:传送门 思路:就是判断无向图的欧拉回路的两个条件:(1)连通性(2)点的度数是偶数 注意:两个条件一同时满足才行. #include<iostream> #include< ...
- 第37章:MongoDB-集群--Replica Sets(副本集)---单机的搭建
①创建副本集 1:先创建几个存放数据的文件夹,比如在前面的dbs下面创建db1,db2,db3: 同理在前面的logs下面创建logs1,logs2,logs3 2:在启动MongoDB服务器的时候, ...
- Linux下nautilus的右键快捷菜单项设置
某一天我的Linux更新完后, 我照常在文件夹下点击右键想打开终端, 却发现右键快捷菜单没有Open in terminal的菜单项了. 在网上查找了一下, 结合自己系统的情况发现了解决办法. 由于我 ...
- Django Class Based View
本节内容 一 Class Based View 基于类的视图 1. 类的视图 View 2. 类的视图 TemplateView 3. 类的视图 login_required解决方法 二 ...
- lgwr的两种模式(post/wait和polling)
11.2之前,oracle的lgwr写入模式为post/wait 11.2之后新增了polling模式,可以与post/wait模式自动切换 通过隐藏参数 _use_adaptive_log_file ...
- 如果你要查看文件的每个部分是谁修改的, 那么 git blame 就是不二选择
原文: http://gitbook.liuhui998.com/5_5.html 如果你要查看文件的每个部分是谁修改的, 那么 git blame 就是不二选择. 只要运行'git blame [f ...
- Bashu2445 -- 【网络流24题-10】餐巾问题
2445 -- [网络流24题-10]餐巾问题 Description 一个餐厅在相继的n天里,每天需要用的餐巾数不尽相同.假设第i天需要ri块餐巾(i=1,2,…,n).餐厅可以购买新的餐巾,每块餐 ...
- Go语言常量
常量是一个简单值的标识符,在程序运行时,不会被修改的量. 常量中的数据类型只能是布尔型.数字型(整数型.浮点型和复数)和字符串型. 常量的定义格式: //const 常量名 类型 值 const id ...
- 使用jedis连接redis
1.导入jar包,添加pom依赖<dependency><groupId>redis.clients</groupId><artifactId>jedi ...