题目描述

已知一棵特殊的二叉查找树。根据定义,该二叉查找树中每个结点的数据值都比它左儿子结点的数据值大,而比它右儿子结点的数据值小。

另一方面,这棵查找树中每个结点都有一个权值,每个结点的权值都比它的儿子结点的权值要小。

已知树中所有结点的数据值各不相同;所有结点的权值也各不相同。这时可得出这样一个有趣的结论:如果能够确定树中每个结点的数据值和权值,那么树的形态便可以唯一确定。因为这样的一棵树可以看成是按照权值从小到大顺序插入结点所得到的、按照数据值排序的二叉查找树。

一个结点在树中的深度定义为它到树根的距离加1。因此树的根结点的深度为1。

每个结点除了数据值和权值以外,还有一个访问频度。我们定义一个结点在树中的访问代价为它的访问频度乘以它在树中的深度。整棵树的访问代价定义为所有结点在树中的访问代价之和。

现在给定每个结点的数据值、权值和访问频度,你可以根据需要修改某些结点的权值,但每次修改你会付出K的额外修改代价。你可以把结点的权值改为任何实数,但是修改后所有结点的权值必须仍保持互不相同。现在你要解决的问题是,整棵树的访问代价与额外修改代价的和最小是多少?

输入输出格式

输入格式:

输入文件中的第一行为两个正整数N,K。其中:N表示结点的个数,K表示每次修改所需的额外修改代价。

接下来的一行为N个非负整数,表示每个结点的数据值。

再接下来的一行为N个非负整数,表示每个结点的权值。

再接下来的一行为N个非负整数,表示每个结点的访问频度。

其中:所有的数据值、权值、访问频度均不超过400000。每两个数之间都有一个空格分隔,且行尾没有空格。

输出格式:

输出文件中仅一行为一个数,即你所能得到的整棵树的访问代价与额外修改代价之和的最小值。

输入输出样例

输入样例#1:

4 10
1 2 3 4
1 2 3 4
1 2 3 4
输出样例#1:

29

说明

【样例说明】

输入的原图是左图,它的访问代价是:1×1+2×2+3×3+4×4=30。

最佳的修改方案是把输入中的第3个结点的权值改成0,得到右图,访问代价是:1×2+2×3+3×1+4×2=19,加上额外修改代价10,一共是29。

【数据规模和约定】

对于40%的数据,满足:N<=30;

对于70%的数据,满足:N<=50;

对于100%的数据,满足:N<=70,1<=K<=30000000。

昨天的考试题。。。昨天不会,写了个rand100000次的萎烂做法,竟然此题得到了零分的好成绩!!!然后今天看了一遍题解。。。
和加分二叉树有点像。。。一个区间DP,因为树的中序遍历一定确定,所以只需在一个区间里枚举根,然后统计答案。。。状态就设f[i][j][e]为i~j的子树而且子树中所有权值都大于e的最小代价(所以需要离散化)。。。每个f需要加上这里面的访问频度,然后就可以一层一层加上去了。。。。。。
正确性的证明:不会

 // It is made by XZZ
#include<cstdio>
#include<algorithm>
#include<cstring>
using namespace std;
#define rep(a,b,c) for(rg int a=b;a<=c;a++)
#define drep(a,b,c) for(rg int a=b;a>=c;a--)
#define erep(a,b) for(rg int a=fir[b];a;a=nxt[a])
#define il inline
#define rg register
#define vd void typedef long long ll;
il int gi(){
rg int x=;rg char ch=getchar();
while(ch<''||ch>'')ch=getchar();
while(ch>=''&&ch<='')x=x*+ch-'',ch=getchar();
return x;
}
struct node{ll d,w,n;}a[];
il bool cmp(node kk,node kkk){return kk.w<kkk.w;}
il bool cmp2(node kk,node kkk){return kk.d<kkk.d;}
ll f[][][];
ll num[];
int main(){
rg int n=gi();rg ll K=gi();
rep(i,,n)a[i].d=gi();
rep(i,,n)a[i].w=gi(),num[i]=a[i].w;
rep(i,,n)a[i].n=gi();
sort(a+,a++n,cmp2);
rep(i,,n)a[i].n+=a[i-].n;
sort(num+,num++n);
int mn=unique(num+,num++n)-num-;
rep(i,,n)a[i].w=lower_bound(num+,num++mn,a[i].w)-num;
rep(siz,,n-)rep(i,,n-siz)rep(e,,mn){
ll&now=f[i][i+siz][e];now=2333333333333333333ll;
rg int l=i,r=i+siz;
rep(k,l,r){
if(a[k].w>=e)now=min(now,f[l][k-][a[k].w]+f[k+][r][a[k].w]+a[r].n-a[l-].n);
now=min(now,K+f[l][k-][e]+f[k+][r][e]+a[r].n-a[l-].n);
}
}
ll ans=f[][n][];
rep(i,,mn)ans=min(ans,f[][n][i]);
printf("%lld\n",ans);
return ;
}

[bzoj1564]二叉查找树的更多相关文章

  1. 【BZOJ1564】【NOI2009】二叉查找树(动态规划)

    [BZOJ1564][NOI2009]二叉查找树(动态规划) 题面 BZOJ 洛谷 题目描述 已知一棵特殊的二叉查找树.根据定义,该二叉查找树中每个结点的数据值都比它左儿子结点的数据值大,而比它右儿子 ...

  2. BZOJ1564 NOI2009二叉查找树(区间dp)

    首先按数据值排序,那么连续一段区间的dfs序一定也是连续的. 将权值离散化,设f[i][j][k]为i到j区间内所有点的权值都>=k的最小代价,转移时枚举根考虑是否修改权值即可. #includ ...

  3. [BZOJ1564][NOI2009]二叉查找树 树形dp 区间dp

    1564: [NOI2009]二叉查找树 Time Limit: 10 Sec  Memory Limit: 64 MBSubmit: 879  Solved: 612[Submit][Status] ...

  4. [BZOJ1564][NOI2009]二叉查找树(区间DP)

    题目:http://www.lydsy.com:808/JudgeOnline/problem.php?id=1564 分析: 首先因为每个点的数据值不变,所以无论树的形态如何变,树的中序遍历肯定不变 ...

  5. bzoj1564: [NOI2009]二叉查找树

    dp. 首先这棵树是一个treap. 权值我们可以改成任意实数,所以权值只表示相互之间的大小关系,可以离散化. 树的中序遍历是肯定确定的. 用f[l][r][w]表示中序遍历为l到r,根的权值必须大于 ...

  6. 数据结构:二叉查找树(C语言实现)

    数据结构:二叉查找树(C语言实现) ►写在前面 关于二叉树的基础知识,请看我的一篇博客:二叉树的链式存储 说明: 二叉排序树或者是一棵空树,或者是具有下列性质的二叉树: 1.若其左子树不空,则左子树上 ...

  7. 数据结构笔记--二叉查找树概述以及java代码实现

    一些概念: 二叉查找树的重要性质:对于树中的每一个节点X,它的左子树任一节点的值均小于X,右子树上任意节点的值均大于X. 二叉查找树是java的TreeSet和TreeMap类实现的基础. 由于树的递 ...

  8. codevs 1285 二叉查找树STL基本用法

    C++STL库的set就是一个二叉查找树,并且支持结构体. 在写结构体式的二叉查找树时,需要在结构体里面定义操作符 < ,因为需要比较. set经常会用到迭代器,这里说明一下迭代器:可以类似的把 ...

  9. 平衡二叉查找树(AVL)的理解与实现

    AVL树的介绍 平衡二叉树,又称AVL(Adelson-Velskii和Landis)树,是带有平衡条件的二叉查找树.这个平衡条件必须要容易保持,而且它必须保证树的深度是 O(log N).一棵AVL ...

随机推荐

  1. 使用plugins让打包更便捷

    之前运行dist下的js,都是手动把index.html拷贝过去的,每次把dist文件夹删除,都需要将index.html拷贝进去,这样很麻烦,我们在webpack官方插件中找到HtmlWebpack ...

  2. [19/04/17-星期三] Java的动态性_反射(Reflection)机制

    一.前言 动态语言:程序运行时,可以改变程序结构或变量类型.典型的代表:Python,ruby,JavaScript 如JavaScript代码: function test(){ var s=&qu ...

  3. 【react】慕课网视频学习笔记

    1.JSX:语法糖,对语言的功能并没有影响,但更方便程序员使用,增强可读性. 2.jsFiddle:前端在线调试工具 3.为什么要把this额外声明成_self变量,因为window.setTimeo ...

  4. selenium + python自动化测试unittest框架学习(三)webdriver元素操作(二)

    上一篇是元素的定位,那么定位元素的目的就是对元素进行操作,例如写入文本,点击按钮,拖动等等的操作 (1)简单元素操作 简单元素操作 find_element_by_id("kw") ...

  5. Maven下使用Junit对Spring进行单元测试

    主要步骤 1. 在工程的pom文件中增加spring-test的依赖: <dependency> <groupId>org.springframework</groupI ...

  6. 所有流媒体协议,编解码规范和媒体封装格式的datasheet的下载地址

    https://github.com/jiayayao/DataSheet All datasheet about stream protocol, encode-decode spec and me ...

  7. 树莓派 4G模块 PPP 拨号 NDIS 拨号

    资料参考:树莓派使用4G模块(华为ME909s-821)亲身尝试的可行方法(上)

  8. docker安装mongodb4.0

    ubantu下的docker安装mongodb4.0. step 1:docker pull mongo:4 step2: docker images step3:启动一个MongoDB服务器容器  ...

  9. VirtualBox + CentOS详细安装教程

    一.前期工作准备 电脑虚拟化开启(必要工作)大致流程: a.电脑开机时长按F12(F10)进入BIOS界面; b.依次选择Configuratio > Intel Virtual Technol ...

  10. 13JavaScript运算符

    运算符 = 用于给 JavaScript 变量赋值. 算术运算符 + 用于把值加起来 实例 指定变量值,并将值相加: y=5; z=2; x=y+z; 在以上语句执行后,x 的值是:7 1.JavaS ...