[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]\)表示在 ...
随机推荐
- JavaSE 初学进度条JProgressBar
预备知识 创建进度条类后将其直接加入JFrame看看效果 public class JProgressBarDemo2 { public static void main(String args[]) ...
- <fieldset>标签
<!DOCTYPE html> <html lang="en"> <head> <meta http-equiv="Conten ...
- Maven二
1 回顾 1.1 Maven的好处 节省空间 对jar包做了统一管理 依赖管理 一键构建 可跨平台 应用在大型项目可提高开发效率 1.2 Maven安装部署配置 1.3 Maven的仓库 本地仓库 远 ...
- form表单数据进行json转换
$.fn.serializeJson = function() { var o = {}; var a = this.serializeArray(); $.each(a, function() { ...
- Qt中的CSS配置(QDarkStyleSheet)
QDarkStylesheet gihub地址 https://github.com/ColinDuquesnoy/QDarkStyleSheet
- 用VerilogHDL设计一个与门逻辑,并进行前仿和后仿
执行菜单命令[File]-[New Project Wizard…],创建工程向导. 在What is the working directory for this project?下选择项目存储地址 ...
- 利用IP核设计高性能的计数器
利用Quartus II的LPM_counter IP核进行设计(利用IP核设计可以迅速高效的完成产品的设计) 新建工程 调用IP核 创建一个新的IP核 选择LMP_COUNTER,语言类型,输出路径 ...
- Python json和pickle模块
用于序列化的两个模块 json,用于字符串 和 python数据类型间进行转换 pickle,用于python特有的类型 和 python的数据类型间进行转换 Json模块提供了四个功能:dumps. ...
- What does git fsck stand for?
fsck -> File System ChecK https://stackoverflow.com/questions/21151945/what-does-git-fsck-stand-f ...
- jQuery应用实例4:下拉列表
应用场景:左侧是已有商品,右侧是未有商品,选择其中的内容点击箭头即可互换: 点击大箭头则全部内容去另一边,或者双击已有商品的选项也会加入右边: 代码实现: <!DOCTYPE html> ...