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] 道路的更多相关文章

  1. 【BZOJ5290】 [Hnoi2018]道路

    BZOJ5290 [Hnoi2018]道路 前言 这道题目我竟然没有在去年省选切? 我太菜了. Solution 对题面进行一个语文透彻解析,发现这是一个二叉树,乡村都是叶子节点,城市都有两个儿子.( ...

  2. 5290: [Hnoi2018]道路

    5290: [Hnoi2018]道路 链接 分析: 注意题目中说每个城市翻新一条连向它的公路或者铁路,所以两种情况分别转移一下即可. 注意压一下空间,最后的叶子节点不要要访问,空间少了一半. 代码: ...

  3. [HNOI2018]道路 --- 树形DP

    [HNOI2018]道路 题目描述: W 国的交通呈一棵树的形状.W 国一共有 \(n-1\) 个城市和 \(n\) 个乡村, 其中城市从 \(1\) 到 \(n-1\) 编号,乡村从 \(1\) 到 ...

  4. 【BZOJ5290】[HNOI2018]道路(动态规划)

    [BZOJ5290][HNOI2018]道路(动态规划) 题面 BZOJ 洛谷 题目直接到洛谷上看吧 题解 开始写写今年省选的题目 考场上我写了一个模拟退火骗了\(90\)分...然而重测后只剩下45 ...

  5. bzoj 5290: [Hnoi2018]道路

    Description Solution PJDP毁青春 注意到性质:到根的道路不超过 \(40\) 条 所以我们只关系一个点上面的道路的情况就行了 设 \(f[x][i][j]\) 表示一个点 \( ...

  6. [HNOI2018]道路(DP)

    题目描述 W 国的交通呈一棵树的形状.W 国一共有n−1n - 1n−1 个城市和nnn 个乡村,其中城市从111 到n−1n - 1n−1 编号,乡村从111 到nnn 编号,且111 号城市是首都 ...

  7. 洛谷4438 [Hnoi2018]道路 【树形dp】

    题目 题目太长懒得打 题解 HNOI2018惊现普及+/提高? 由最长路径很短,设\(f[i][x][y]\)表示\(i\)号点到根有\(x\)条未修公路,\(y\)条未修铁路,子树所有乡村不便利值的 ...

  8. [洛谷P4438] HNOI2018 道路

    问题描述 W 国的交通呈一棵树的形状.W 国一共有n - 1个城市和n个乡村,其中城市从1到n - 1 编号,乡村从1到n编号,且1号城市是首都.道路都是单向的,本题中我们只考虑从乡村通往首都的道路网 ...

  9. BZOJ.5290.[AHOI/HNOI2018]道路(树形DP)

    BZOJ LOJ 洛谷 老年退役选手,都写不出普及提高DP= = 在儿子那统计贡献,不是在父亲那统计啊!!!(这样的话不写这个提高DP写记忆化都能过= =) 然后就令\(f[x][a][b]\)表示在 ...

随机推荐

  1. LAMP简介与部署

    lamp简介 lamp,是由Linux+Apache+Mysql/MariaDB+Php/Perl/Python的一组动态网站或者服务器的开源软件,除Linux外其它各部件本身都是各自独立的程序,但是 ...

  2. js禁用浏览器后退

    history.pushState(null, null, document.URL); window.addEventListener('popstate', function () { histo ...

  3. Maths | 二次型求偏导

  4. 如何将他人的SOPC工程转换为自己可以使用的工程

    上篇文章的程序源码在:http://download.csdn.net/detail/noticeable/9921952 源码错误现象: 在下载源码文件解压后,打开系统工程,可以看到quartus ...

  5. WITH RECOMPILE和OPTION(RECOMPILE)区别仅仅是存储过程级重编译和SQL语句级重编译吗

    在考虑重编译T-SQL(或者存储过程)的时候,有两种方式可以实现强制重编译(前提是忽略导致重编译的其他因素的情况下,比如重建索引,更新统计信息等等), 一是基于WITH RECOMPILE的存储过程级 ...

  6. Spring Data Solr的分组查询 for 搜索面板的商品分类

    private List searchCategoryList(Map searchMap) { SimpleQuery query = new SimpleQuery(new Criteria(&q ...

  7. 在Java Web中使用Spark MLlib训练的模型

    PMML是一种通用的配置文件,只要遵循标准的配置文件,就可以在Spark中训练机器学习模型,然后再web接口端去使用.目前应用最广的就是基于Jpmml来加载模型在javaweb中应用,这样就可以实现跨 ...

  8. jQuery基础与JavaScript与CSS交互-第五章

    目录 JavaScript框架种类及其优缺点 jQuery库 jQuery对象$ 掌握基本选择器 掌握过滤选择器 掌握表单选择器 RIA技术 常见的RIA技术 Ajax Sliverlight Fle ...

  9. Netty 发送消息失败或者接收消息失败的可能原因

    1. 消息发送失败: 检查通道是否建立成功 Netty中的通道建立采用的是异步方式,获取到的通道对象可能为空或初始化未完成: 2. 接收的消息有丢失 消息可能会粘包,是否有拆包机制

  10. Ubuntu 16.04 安装 arm-linux-gcc 交叉编译工具

    工作需要,最近在编译linux嵌入式内核时,需要安装arm-linux-gcc交叉编译,实际上,安装这个交叉编译器的难度没啥.不过,这里有些问题还是值得我去思考和记录下来的. 这个系统的上的编译器用的 ...