BZOJ 1564 :[NOI2009]二叉查找树(树型DP)
二叉查找树
【题目描述】
已知一棵特殊的二叉查找树。根据定义,该二叉查找树中每个结点的数据值都比它左儿子结点的数据值大,而比它右儿子结点的数据值小。
另一方面,这棵查找树中每个结点都有一个权值,每个结点的权值都比它的儿子结点的权值要小。
已知树中所有结点的数据值各不相同;所有结点的权值也各不相同。这时可得出这样一个有趣的结论:如果能够确定树中每个结点的数据值和权值,那么树的形态便可以唯一确定。因为这样的一棵树可以看成是按照权值从小到大顺序插入结点所得到的、按照数据值排序的二叉查找树。
一个结点在树中的深度定义为它到树根的距离加1。因此树的根结点的深度为1。
每个结点除了数据值和权值以外,还有一个访问频度。我们定义一个结点在树中的访问代价为它的访问频度乘以它在树中的深度。整棵树的访问代价定义为所有结点在树中的访问代价之和。
现在给定每个结点的数据值、权值和访问频度,你可以根据需要修改某些结点的权值,但每次修改你会付出K的额外修改代价。你可以把结点的权值改为任何实数,但是修改后所有结点的权值必须仍保持互不相同。现在你要解决的问题是,整棵树的访问代价与额外修改代价的和最小是多少?
【输入格式】
输入文件中的第一行为两个正整数N,K。其中:N表示结点的个数,K表示每次修改所需的额外修改代价。
接下来的一行为N个非负整数,表示每个结点的数据值。
再接下来的一行为N个非负整数,表示每个结点的权值。
再接下来的一行为N个非负整数,表示每个结点的访问频度。
其中:所有的数据值、权值、访问频度均不超过400000。每两个数之间都有一个空格分隔,且行尾没有空格。
【输出格式】
输出文件中仅一行为一个数,即你所能得到的整棵树的访问代价与额外修改代价之和的最小值。
【样例输入】
4 10
1 2 3 4
1 2 3 4
1 2 3 4
【样例输出】
29
分析:
参加比赛遇到的题目,比赛时看到题目感觉是用树型dp,但一直没有思路,只好用近似模拟的方法乱搞的,后来看了题解才会做......
首先我们知道该树是一颗特殊的二叉排序树,它比普通的多一个优先级(在本题中就是权值),使它有了堆的性质。如果没有修改操作,我们可以根据这些性质构造一颗这样的树然后模拟,而本题的难度就在修改,对此可以用动规解决。
定义f[i,j,w]为第i..j的节点构成节点权值大于w的子树遍历的最小代价,a[i,1]保存节点的数据值,a[i,2]保存节点离散化后的权值,a[i,3]保存节点的访问频度,s[i,j]为第i..j的节点访问频度之和。
离散化权值,就是将权值按从小到大排序后用其在数组中编号来表示其权值,之所以能这样做是因为节点权值各部相同,而每个点权值数字本身多少没有意义,重要的是它与其它节点权值相比的大小关系,离散化后就可以将大小参差不齐的数字按大小的关系转换为有序的编号,可以节省空间,也可省去动规中的一些麻烦的东西。
分两种情况
在i..j中枚举根节点k
若不修改,条件是k的权值>=w,则f[i,j,w]:=max(f[i,j,w],f[i,k-1,a[k,2]]+f[k+1,j,a[k,2]]+s[i,j])
若修改,则f[i,j,w]:=max(f[i,j,w],f[i,k-1,w]+f[k+1,j,w]+s[i,j]+k)
解释:如果不修改,k必须在子树中,其左右孩子权值均要大于k的权值;如果将k修改为根节点,其左右孩子权值可比w大很小很小的一个数字。
代码
program treap;
var
f:array[..,..,..]of longint;
a:array[..,..]of longint;
s:array[..,..]of longint;
n,i,m,j,w,k:longint;
function min(x,y:longint):longint;
begin
if x<y then min:=x else min:=y;
end;
procedure sort(x:longint);
var i,j,t:longint;
begin
for i:= to n- do
for j:=i+ to n do
if a[x,i]>a[x,j] then
begin
t:=a[,i]; a[,i]:=a[,j]; a[,j]:=t;
t:=a[,i]; a[,i]:=a[,j]; a[,j]:=t;
t:=a[,i]; a[,i]:=a[,j]; a[,j]:=t;
end;
end;
begin
assign(input,'treap.in');
reset(input);
assign(output,'treap.out');
rewrite(output);
readln(n,m);
for i:= to n do
read(a[,i]); readln;
for i:= to n do
read(a[,i]); readln;
for i:= to n do
read(a[,i]);
sort();
for i:= to n do
a[,i]:=i;
sort();
for i:= to n do
for j:=i to n do
s[i,j]:=s[i,j-]+a[,j];
for i:= to n do
for j:= to n do
for w:= to n do
f[i,j,w]:=maxlongint div ;
for i:= to n+ do
for w:= to n do
f[i,i-,w]:=;
for w:=n downto do
for i:=n downto do
for j:=i to n do
for k:=i to j do
if i=j then
if a[,k]>=w then f[i,j,w]:=a[,k] else f[i,j,w]:=a[,k]+m
else begin
if a[,k]>=w then f[i,j,w]:=min(f[i,j,w],f[i,k-,a[,k]]+f[k+,j,a[,k]]+s[i,j]);
f[i,j,w]:=min(f[i,j,w],f[i,k-,w]+f[k+,j,w]+s[i,j]+m);
end;
writeln(f[,n,]);
close(input); close(output);
end.
BZOJ 1564 :[NOI2009]二叉查找树(树型DP)的更多相关文章
- bzoj 1564 [NOI2009]二叉查找树(树形DP)
[题目链接] http://www.lydsy.com/JudgeOnline/problem.php?id=1564 [题意] 给定一个Treap,总代价为深度*距离之和.可以每次以K的代价修改权值 ...
- BZOJ 1564: [NOI2009]二叉查找树( dp )
树的中序遍历是唯一的. 按照数据值处理出中序遍历后, dp(l, r, v)表示[l, r]组成的树, 树的所有节点的权值≥v的最小代价(离散化权值). 枚举m为根(p表示访问频率): 修改m的权值 ...
- bzoj 1564 [NOI2009]二叉查找树 区间DP
[NOI2009]二叉查找树 Time Limit: 10 Sec Memory Limit: 64 MBSubmit: 906 Solved: 630[Submit][Status][Discu ...
- BZOJ 1564: [NOI2009]二叉查找树
链接:http://www.lydsy.com/JudgeOnline/problem.php?id=1564 Description Input Output 只有一个数字,即你所能得到的整棵树的访 ...
- BZOJ 2286 消耗战 - 虚树 + 树型dp
传送门 题目大意: 每次给出k个特殊点,回答将这些特殊点与根节点断开至少需要多少代价. 题目分析: 虚树入门 + 树型dp: 刚刚学习完虚树(好文),就来这道入门题签个到. 虚树就是将树中的一些关键点 ...
- BZOJ 1509 逃学的小孩 - 树型dp
传送门 题目大意: 在一棵树中, 每条边都有一个长度值, 现要求在树中选择 3 个点 X.Y. Z , 满足 X 到 Y 的距离不大于 X 到 Z 的距离, 且 X 到 Y 的距离与 Y 到 Z 的距 ...
- BZOJ 1864 三色二叉树 - 树型dp
传送门 题目大意: 给一颗二叉树染色红绿蓝,父亲和儿子颜色必须不同,两个儿子颜色必须不同,问最多和最少能染多少个绿色的. 题目分析: 裸的树型dp:\(dp[u][col][type]\)表示u节点染 ...
- POJ3659 Cell Phone Network(树上最小支配集:树型DP)
题目求一棵树的最小支配数. 支配集,即把图的点分成两个集合,所有非支配集内的点都和支配集内的某一点相邻. 听说即使是二分图,最小支配集的求解也是还没多项式算法的.而树上求最小支配集树型DP就OK了. ...
- POJ 3342 - Party at Hali-Bula 树型DP+最优解唯一性判断
好久没写树型dp了...以前都是先找到叶子节点.用队列维护来做的...这次学着vector动态数组+DFS回朔的方法..感觉思路更加的清晰... 关于题目的第一问...能邀请到的最多人数..so ea ...
随机推荐
- codeforce Gym 100425E The Street Escalator(期望,线性递推)
算数学期望,每个人都可以分开来考虑.Xi表示第i个人跑到另外一边的次数. Xi服从二项分布.概率的和是个二项式,(p+1-p)^T,把二项式展开,p的偶次项是留在原来那一边的概率. 可以用((a+b) ...
- POJ-2135 Farm Tour---最小费用最大流模板题(构图)
题目链接: https://vjudge.net/problem/POJ-2135 题目大意: 主人公要从1号走到第N号点,再重N号点走回1号点,同时每条路只能走一次. 这是一个无向图.输入数据第一行 ...
- 2017.12.13 Java中是怎样通过类名,创建一个这个类的数组
先在类方法中定义数组的方法: public int[] method6(int[] arr){ for(int i = 0; i<arr.length;i++){ arr[i] = (int)( ...
- Luogu P1471 方差
题目传送门 开了十倍空间才过是什么鬼?该不会我线段树炸了吧-- 细思极恐 平均数都会求,维护区间和,到时候除一下就好了. 方差的求法如下 (用的Luogu的图片) 因为要维护一个平方,我们可以考虑使用 ...
- java基础编程——二维数组中的查找
题目描述 在一个二维数组中(每个一维数组的长度相同),每一行都按照从左到右递增的顺序排序,每一列都按照从上到下递增的顺序排序.请完成一个函数,输入这样的一个二维数组和一个整数,判断数组中是否含有该整数 ...
- ubuntu web server ipython notebook install
http://blog.csdn.net/yehuohan/article/details/51389966 ipython notebook installhttp://blog.csdn.net/ ...
- 爬虫学习(六)——异常处理URLerrors异常处理
# 异常处理都在urllib.error中进行处理 import urllib.requestimport urllib.error # 第一种异常:该网址不存在url = "http:// ...
- MySQL - GROUP_CONCAT 使用方法
如上图,我想把结果集中的三行链接成一行,则可这样写: 总结: GROUP_CONCAT函数默认是用','逗号链接,如果你加上第二个参数,则以',第二个参数值'逗号+第二个参数值链接,如下图 ...
- ajax全局变量的使用
var username; $.ajax({ type:"post", url:"a.action", data: {}, dataType: 'text', ...
- 常见react面试题汇总
已经开源 地址:https://github.com/nanhupatar...关注我们团队: React 中 keys 的作用是什么? Keys 是 React 用于追踪哪些列表中元素被修改.被添加 ...