链接: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. varchar(n),nvarchar(n) 长度、性能、及所占空间的说明

    varchar(n),nvarchar(n) 中的n怎么解释: nvarchar(n)最多能存n个字符,不区分中英文. varchar(n)最多能存n个字节,一个中文是两个字节. 所占空间: nvar ...

  2. VS使用过程中,编写JS没有智能提示解决方法

    问题:编写基本Script代码没有问题,但是在编写DOM代码时候没有智能提示.也就是在编写一般javascript代码时候没有问题,但是要写DOM代码的时候发现没有智能提示,如document等都需要 ...

  3. YII2学习第一天

    YII2学习第一天,之前稍微看了看TP,感觉和自己的理念不是很符合,然后转学YII2了. 使用的文档是https://github.com/yiisoft/yii2/tree/master/docs/ ...

  4. C#中Invoke 和 BeginInvoke 的区别

    Control.Invoke 方法 (Delegate) :在拥有此控件的基础窗口句柄的线程上执行指定的委托. Control.BeginInvoke 方法 (Delegate) :在创建控件的基础句 ...

  5. C#创建文件夹

    string path = Server.MapPath("~/DefaultImg/newDir/63/");//获取文件路径 if (!Directory.Exists(pat ...

  6. DIOCP之工作流程图

    晚上更新,请大家多多理解,最近比较忙

  7. SqlServer传输数据到ORACLE,SSIS

    一.配置32位ODBC 配置tnsname文件,增加ORACLE数据库 打开32位ODBC 二.创建一个PROJECT并配置数据源 1.创建一个project 三.数据传输SSIS,工作流 四.为DT ...

  8. LinckedhashMap原理

    http://zhangshixi.iteye.com/blog/673789 TreeMap的key是有顺序的,是自然顺序,也可以指定比较函数. 但默认不是按插入的顺序.  为了让Map  JSON ...

  9. SVN冲突解决:当次提交的和上次提交的出现冲突

    转载于知蚁博客,文章地址:http://www.letuknowit.com/archives/svn-conflict-resolution 看到那个*了吧,出现这个标记就说明本地副本的文件已经过期 ...

  10. Libevent 的多线程操作

    起因是event_base 跨线程add/remove event 导致崩溃或者死循环. 据查:libvent 1.4.x是非线程安全的,要跨线程执行event_add,会有问题.因此传统做法是通过p ...