[洛谷P1864] NOI2009 二叉查找树
问题描述
已知一棵特殊的二叉查找树。根据定义,该二叉查找树中每个结点的数据值都比它左儿子结点的数据值大,而比它右儿子结点的数据值小。
另一方面,这棵查找树中每个结点都有一个权值,每个结点的权值都比它的儿子结点的权值要小。
已知树中所有结点的数据值各不相同;所有结点的权值也各不相同。这时可得出这样一个有趣的结论:如果能够确定树中每个结点的数据值和权值,那么树的形态便可以唯一确定。因为这样的一棵树可以看成是按照权值从小到大顺序插入结点所得到的、按照数据值排序的二叉查找树。
一个结点在树中的深度定义为它到树根的距离加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
说明
【样例说明】

输入的原图是左图,它的访问代价是: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。
解析
可以发现,题目所给的意思就是构造了一棵Treap。由于数据值是不会变的,所以根据平衡树的性质,中序遍历也是不会改变的。另外,中序遍历中的一段区间对应着树上的一棵子树,所以,我们可以利用区间DP的思想以及子树根节点的权值是子树中最小的这个性质,得出如下状态:
设\(f[i][j][k]\)表示中序遍历中区间\([i,j]\)得到一棵树且最小权值大于等于k的最小代价。枚举子树的根节点x,如果x的权值小于k,就需要修改权值。我们有如下状态转移方程:
\]
同时,因为根节点两边的子树深度均加1,所以需要再加上i到j的频率之和。
另外,每个点的权值可以直接离散化为1到n,不影响答案。
代码
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
#define N 72
using namespace std;
struct node{
int dat,w,f;
}a[N];
int n,m,i,j,k,l,x,val[N],sum[N],f[N][N][N];
int read()
{
char c=getchar();
int w=0;
while(c<'0'||c>'9') c=getchar();
while(c<='9'&&c>='0'){
w=w*10+c-'0';
c=getchar();
}
return w;
}
int my_comp(const node &x,const node &y)
{
return x.dat<y.dat;
}
int main()
{
n=read();m=read();
for(i=1;i<=n;i++) a[i].dat=read();
for(i=1;i<=n;i++){
a[i].w=read();
val[i]=a[i].w;
}
for(i=1;i<=n;i++) a[i].f=read();
sort(val+1,val+n+1);
sort(a+1,a+n+1,my_comp);
int n1=unique(val+1,val+n+1)-val-1;
for(i=1;i<=n;i++){
a[i].w=lower_bound(val+1,val+n1+1,a[i].w)-val;
sum[i]=sum[i-1]+a[i].f;
}
memset(f,0x3f,sizeof(f));
for(i=1;i<=n+1;i++){
for(k=1;k<=n;k++) f[i][i-1][k]=0;
}
for(l=1;l<=n;l++){
for(i=1;i+l-1<=n;i++){
j=i+l-1;
for(k=1;k<=n;k++){
for(x=i;x<=j;x++){
f[i][j][k]=min(f[i][j][k],f[i][x-1][k]+f[x+1][j][k]+m+sum[j]-sum[i-1]);
if(a[x].w>=k) f[i][j][k]=min(f[i][j][k],f[i][x-1][a[x].w]+f[x+1][j][a[x].w]+sum[j]-sum[i-1]);
}
}
}
}
printf("%d\n",f[1][n][1]);
return 0;
}
反思
并没有注意到这是一个Treap,即使知道了也没有注意到中序遍历不变的性质。所以,多多关注特殊条件特殊性质。
[洛谷P1864] NOI2009 二叉查找树的更多相关文章
- 洛谷$P1864\ [NOI2009]$二叉查找树 区间$dp$
正解:区间$dp$ 解题报告: 传送门$QwQ$ 首先根据二叉查找树的定义可知,数据确定了,这棵树的中序遍历就已经改变了,唯一能改变的就是通过改变权值从而改变结点的深度. 发现这里权值的值没有意义,所 ...
- P1864 [NOI2009]二叉查找树
链接P1864 [NOI2009]二叉查找树 这题还是蛮难的--是我菜. 题目描述中的一大堆其实就是在描述\(treap.\),考虑\(treap\)的一些性质: 首先不管怎么转,中序遍历是确定的,所 ...
- 不失一般性和快捷性地判定决策单调(洛谷P1912 [NOI2009]诗人小G)(动态规划,决策单调性,单调队列)
洛谷题目传送门 闲话 看完洛谷larryzhong巨佬的题解,蒟蒻一脸懵逼 如果哪年NOI(放心我这样的蒟蒻是去不了的)又来个决策单调性优化DP,那蒟蒻是不是会看都看不出来直接爆\(0\)?! 还是要 ...
- 洛谷 P2805 [NOI2009]植物大战僵尸 解题报告
P2805 [NOI2009] 植物大战僵尸 题目描述 Plants vs. Zombies(PVZ)是最近十分风靡的一款小游戏.Plants(植物)和Zombies(僵尸)是游戏的主角,其中Plan ...
- 洛谷 [P1963] [NOI2009] 变换序列
这是一道二分图匹配的题 先%dalao博客 建图并没有什么难的,但是关键在于如何使字典序最小. 一个很显然的想法是先求出一个完美匹配,然后从x集合的第一个元素开始,如果该元素匹配的较小的一个,那么继续 ...
- 洛谷P1963 [NOI2009]变换序列(二分图)
传送门 我可能真的只会网络流……二分图的题一点都做不来…… 首先每个位置有两种取值,所以建一个二分图,只要有完美匹配就说明有解 考虑一下每一个位置,分别让它选择两种取值,如果都不能形成完美匹配,说明无 ...
- 洛谷P1912 [NOI2009]诗人小G(决策单调性)
传送门 题解 决策单调性是个啥……导函数是个啥……这题解讲的是啥……我是个啥…… //minamoto #include<iostream> #include<cstdio> ...
- Luogu P1864 [NOI2009]二叉查找树
题目 \(v\)表示权值,\(F\)表示频率. 首先我们显然可以把这个权值离散化. 然后我们想一下,这个东西它是一棵树对吧,但是我们改变权值会引起其树形态的改变,这样很不好做,所以我们考虑把它转化为序 ...
- 洛谷$P2805\ [NOI2009]$植物大战僵尸 网络流
正解:网络流 解题报告: 传送门$QwQ$ 题面好长昂,,,我大概概括下$QwQ$?有个$n\cdot m$的网格,每个格子有一株植物,击溃一株植物$(x,y)$需要付出$S_{(x,y)}$的代价( ...
随机推荐
- C# 图片文件文本string格式 传输问题
string file = @"E:\test.png"; byte[] bytes = File.ReadAllBytes(file); // 主要代码 string datas ...
- Linux_KVM虚拟机
目录 目录 Hpyervisor的种类 安装KVM 使用virsh指令管理虚拟机 KVM虚拟机的网络设置 Hpyervisor的种类 hpyervisor:是一种VMM(Virtual Machine ...
- MYSQL启用数据库错误:ERROR 2002 (HY000)
ERROR 2002 (HY000): Can't connect to local MySQL server through socket '/tmp/mysql.sock' (2) MYSQL服务 ...
- WinFrom控件双向绑定
using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; usin ...
- java.io.FileNotFoundException: /usr/local/hadoop/logs/fairscheduler-statedump.log(权限不够)解决方案
问题描述:Linux虚拟机内使用hadoop 解决方案: $ su 密码:****** # chown hadoop 文件名 进入超级管理员,为hadoop用户分配该文件的权限. 完美解决:
- Vue 渲染函数
Vue 推荐在绝大多数情况下使用模板来创建你的 HTML.然而在一些场景中,你真的需要 JavaScript 的完全编程的能力.这时你可以用渲染函数,它比模板更接近编译器. 一 项目结构 二 App组 ...
- big data env setup
install Spark on CentOS: https://aodba.com/how-to-install-apache-spark-in-centos-standalone/ https:/ ...
- xmake从入门到精通10:多个子工程目标的依赖配置
xmake是一个基于Lua的轻量级现代化c/c++的项目构建工具,主要特点是:语法简单易上手,提供更加可读的项目维护,实现跨平台行为一致的构建体验. 本文主要详细讲解下,如果在一个项目中维护和生成多个 ...
- docker--docker compose 编排工具
11 docker compose 编排工具 11.1 docker compose 介绍 根据前面所学的知识可知,想要使用Docker部署应用,就要先在应用中编写Dockerfile 文件来构建镜像 ...
- 第四周课程总结与第二次实验报告(Java简单类与对象)
1.写一个名为Rectangle的类表示矩形.其属性包括宽width.高height和颜色color,width和height都是double型的,而color则是String类型的.要求该类具有: ...