链接:http://www.lydsy.com/JudgeOnline/problem.php?id=1564

Description

Input

Output

只有一个数字,即你所能得到的整棵树的访问代价与额外修改代价之和的最小值。

Sample Input

4 10
1 2 3 4
1 2 3 4
1 2 3 4

Sample Output

29
题解:我们还是老规矩设一个区间f[i][j][w]为区间i~j且树上的每个节点都大于等于w(因为子节点权值一定大于根节点,所以其实就是根节点要大于等于w),来形成一棵树的最小访问代价与额外代价之和。
然后枚举一个k把区间分为左边和右边,k为这棵树的根节点,但是为了左儿子数据值小于根节点,k左边的数据值一定小于k,右边一定大于k,我们事先要把数据值从小到大排序,来保证枚举的区间符合条件。枚举k后我们就要判断一下,如果k节点的权值要大于w,那么我们就不用修改,只要把左边子树值加上右边子树的值再加上本身的访问代价即可,(可能会有点奇怪,我们怎么确保左边和右边的权值一定大于我们枚举的这个根节点呢?哈,这就是w的作用啦,左边的值为f[i][k-1][w],说明左边的所有节点都需大于等于w,如果不存在的话,就会是最大值,所以不会被计算进来),如果要修改再额外加上最初输入的k就可以了。还有一个比较重要的地方,我们需要枚举w,可是原题中的w过大,导致空间超限了,这里就需要进行一个离散化,为什么可以这么做呢?我们可以发现他保证了每个权值都不相同且我们判断时只需要利用他的大小关系,与他本身是无关的,所以可以在一开始的时候就排一下序,然后把权值都变小,就搞定了。
具体的细节还是在程序中写吧。
程序:
#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<algorithm>
using namespace std;
int n,j,k1,s[],f[][][];
struct h
{
int x,y,z;
}a[];
bool cmp1(const h&a,const h&b)
{
return (a.y<b.y);
}
bool cmp2(const h&a,const h&b)
{
return (a.x<b.x);
}
int main()
{
scanf("%d %d",&n,&k1);
for (int i=;i<=n;i++) cin>>a[i].x;
for (int i=;i<=n;i++) cin>>a[i].y;
for (int i=;i<=n;i++) cin>>a[i].z;
sort(a+,a++n,cmp1);//按照权值排序
for (int i=;i<=n;i++) a[i].y=i;//进行离散化
sort(a+,a++n,cmp2);//为了符合条件再按照数据值排序
for (int i=;i<=n;i++)
s[i]=s[i-]+a[i].z;//用前缀和把访问频率记录下来,方便计算 for (int i=;i<=n+;i++)
for (int j=;j<=n+;j++)
for (int w=;w<=n+;w++)
f[i][j][w]=;//初始化 for (int i=;i<=n+;i++)
for (int w=;w<=n;w++)
f[i][i-][w]=;//当我们在一个区间中枚举边界i或j为根节点时,我们就会访问到某个f[i][i-1][w],
但其实他是没有左子树或右子树的,所以我们就把它记为0,反正加上去了也没有任何影响。 for (int i=;i<=n;i++)
for (int w=;w<=n;w++)
if (a[i].y>=w) f[i][i][w]=a[i].z;//把本身当做一棵树且这棵树的权值大于等于w时,不必修改。
else f[i][i][w]=a[i].z+k1;//否则就要加上修改的代价 for (int w=n;w>=;w--)
for (int len=;len<=n;len++)
for (int i=;i<=n-len+;i++)//枚举
{
j=i+len-;
for (int k=i;k<=j;k++)
{
if (a[k].y>=w)
f[i][j][w]=min(f[i][j][w],f[i][k-][a[k].y]+f[k+][j][a[k].y]+s[j]-s[i-]);//不需修改时
f[i][j][w]=min(f[i][j][w],f[i][k-][w]+f[k+][j][w]+s[j]-s[i-]+k1); //修改时
}
}
printf("%d",f[][n][]);//因为离散化后节点中权值最小的是1,所以根节点的权值一定是1.
return ;
}

BZOJ 1564: [NOI2009]二叉查找树的更多相关文章

  1. BZOJ 1564: [NOI2009]二叉查找树( dp )

    树的中序遍历是唯一的. 按照数据值处理出中序遍历后, dp(l, r, v)表示[l, r]组成的树, 树的所有节点的权值≥v的最小代价(离散化权值). 枚举m为根(p表示访问频率): 修改m的权值 ...

  2. bzoj 1564 [NOI2009]二叉查找树 区间DP

    [NOI2009]二叉查找树 Time Limit: 10 Sec  Memory Limit: 64 MBSubmit: 906  Solved: 630[Submit][Status][Discu ...

  3. bzoj 1564 [NOI2009]二叉查找树(树形DP)

    [题目链接] http://www.lydsy.com/JudgeOnline/problem.php?id=1564 [题意] 给定一个Treap,总代价为深度*距离之和.可以每次以K的代价修改权值 ...

  4. BZOJ 1564 :[NOI2009]二叉查找树(树型DP)

    二叉查找树 [题目描述] 已知一棵特殊的二叉查找树.根据定义,该二叉查找树中每个结点的数据值都比它左儿子结点的数据值大,而比它右儿子结点的数据值小. 另一方面,这棵查找树中每个结点都有一个权值,每个结 ...

  5. 1564: [NOI2009]二叉查找树 - BZOJ

    Description Input Output只有一个数字,即你所能得到的整棵树的访问代价与额外修改代价之和的最小值.Sample Input4 101 2 3 41 2 3 41 2 3 4Sam ...

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

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

  7. bzoj 1565 [NOI2009]植物大战僵尸 解题报告

    1565: [NOI2009]植物大战僵尸 Time Limit: 10 Sec  Memory Limit: 64 MBSubmit: 2161  Solved: 1000[Submit][Stat ...

  8. P1864 [NOI2009]二叉查找树

    链接P1864 [NOI2009]二叉查找树 这题还是蛮难的--是我菜. 题目描述中的一大堆其实就是在描述\(treap.\),考虑\(treap\)的一些性质: 首先不管怎么转,中序遍历是确定的,所 ...

  9. NOI2009 二叉查找树 【区间dp】

    [NOI2009]二叉查找树 [问题描述] 已知一棵特殊的二叉查找树.根据定义,该二叉查找树中每个结点的数据值都比它左子树结点的数据值大,而比它右子树结点的数据值小.另一方面,这棵查找树中每个结点都有 ...

随机推荐

  1. 移动端click事件延迟300ms的原因以及解决办法

    这要追溯至 2007 年初.苹果公司在发布首款 iPhone 前夕,遇到一个问题 —— 当时的网站都是为大屏幕设备所设计的.于是苹果的工程师们做了一些约定,应对 iPhone 这种小屏幕浏览桌面端站点 ...

  2. Qt事件过滤器Event Filter

    事件过滤器针对一类或者多种不同类型的对象,定义了重写操作. 简单的说: 1.先对UI对象注册Event Filter 例如:    ui->drawBtn->installEventFil ...

  3. centos7安装mariadb10遇到的问题解决

    4. 安装中的错误 4.1 /bin/ld: cannot find -lz /bin/ld: cannot find -lzcollect2: error: ld returned 1 exit s ...

  4. Android笔记之——事件的发生(2)

    Java: package com.example.helloworld;import android.os.Bundle;import android.view.KeyEvent;import an ...

  5. 运行WPS遇到的问题及解决办法

    http://www2.mmm.ucar.edu/wrf/OnLineTutorial/Class/cases/find_the_bugs.php# For this case we are goin ...

  6. svn各个图标代表什么意思

    最近参与公司项目开发要使用SVN,下面随笔记下在使用SVN中常见的图标各代表什么意思 灰色向右箭头:本地修改过 ,本地代码没有及时上库.灰色向右且中间有个加号的箭头:本地比SVN上多出的文件灰色向右且 ...

  7. git 创建远程分支和删除 master 分支

    . . . . . 最近需要将不同的客户的代码分开管理,所以需要为这些代码分别创建分支. 目前版本库中分支结构如下: [yuhuashi@local:Project]$ git branch -a* ...

  8. SonarQube-5.6.3 代码分析平台搭建使用

    python代码分析 官网主页: http://docs.sonarqube.org/display/PLUG/Python+Plugin Windows下安装使用: 快速使用: 1.下载jdk ht ...

  9. php js => splice 数组 插入 功能

    php    array_splice 手册详解 array_splice   - 把数组中的一部分去掉并用其它值取代 参数 input 输入的数组. offset 如果 offset 为正,则从 i ...

  10. django单元测试

        django 单元测试小结 django 测试 从前很少写单元测试了,特别是web应用.最近不知不觉喜欢起来这个事情了,发现单元测试对于软件的模块,正交性有很大促进作用,因为函数,模块写的不合 ...