树的中序遍历是唯一的. 按照数据值处理出中序遍历后, dp(l, r, v)表示[l, r]组成的树, 树的所有节点的权值≥v的最小代价(离散化权值).

枚举m为根(p表示访问频率):

修改m的权值 : dp(l, r, v) = min( dp(l, m-1, v) + dp(m+1, r, v) + p(l~r) + K )

不修改(m原先权值≥v) : dp(l, r, v) = min( dp(l, m-1, Value(m)) + dp(m+1, r, Value(m)) + p(l~r) )

时间复杂度O( N log N + N^4 )

-------------------------------------------------------------------------------

#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
 
using namespace std;
 
typedef long long ll;
 
const int maxn = 79;
const ll inf = 1LL << 60;
 
int N, C, H[maxn];
ll dp[maxn][maxn][maxn];
 
template<class T>
inline void Min(T &x, T t) {
if(t < x) x = t;
}
 
struct Node {
int d, v, p;
bool operator < (const Node &o) const {
return d < o.d;
}
} o[maxn];
 
ll Dp(int l, int r, int v) {
if(l > r) return 0;
ll &t = dp[l][r][v];
if(~t) return t;
int d = o[r].p - o[l - 1].p;
if(l == r)
return t = d + (o[l].v >= v ? 0 : C);
t = inf;
for(int i = l; i <= r; i++) {
Min(t, Dp(l, i - 1, v) + Dp(i + 1, r, v) + C + d);
if(o[i].v >= v)
Min(t, Dp(l, i - 1, o[i].v) + Dp(i + 1, r, o[i].v) + d);
}
return t;
}
 
int main() {
scanf("%d%d", &N, &C);
for(int i = 1; i <= N; i++) scanf("%d", &o[i].d);
for(int i = 1; i <= N; i++) scanf("%d", &o[i].v);
for(int i = 1; i <= N; i++) scanf("%d", &o[i].p);
sort(o + 1, o + N + 1);
o[0].p = 0;
for(int i = 1; i <= N; i++) {
o[i].p += o[i - 1].p;
H[i - 1] = o[i].v;
}
sort(H, H + N);
int hn = unique(H, H + N) - H;
for(int i = 1; i <= N; i++)
o[i].v = lower_bound(H, H + hn, o[i].v) - H;
memset(dp, -1, sizeof dp);
ll ans = inf;
for(int i = 0; i < hn; i++)
Min(ans, Dp(1, N, i));
cout << ans << "\n";
return 0;
}

-------------------------------------------------------------------------------

1564: [NOI2009]二叉查找树

Time Limit: 10 Sec  Memory Limit: 64 MB
Submit: 625  Solved: 453
[Submit][Status][Discuss]

Description

Input

Output

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

Sample Input

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

Sample Output

29

HINT

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

Source

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

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

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

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

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

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

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

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

    链接:http://www.lydsy.com/JudgeOnline/problem.php?id=1564 Description Input Output 只有一个数字,即你所能得到的整棵树的访 ...

  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. UITabBarController+微博简单模拟1

    UITabBarController是IOS中很常用的一个viewController.UITabBarController通常作为整个程序的rootViewController,而且不能添加到别的c ...

  2. WindowsAPI一日一练

    1.SetWindowLong和GetWindowLong 函数原型: LONG SetWindowLong( __in HWND hWnd, __in int nIndex, __in LONG d ...

  3. Object转换为JSON格式字符串

    简介: 把JS的Object转换为Json字符串. 代码: function ObjectToJson(object) { // Object转换为josn var json = "&quo ...

  4. Linux下,命令 wget 的使用

    wget是一个从网络上自动下载文件的自由工具.它支持HTTP,HTTPS和FTP协议,可以使用HTTP代理.  所谓的自动下载是指,wget可以在用户退出系统的之后在后台执行.这意味这你可以登录系统, ...

  5. [转]Linux下转换字符集(UTF8转换)

    今天在Linux 下使用 Iconv 命令转换一个UTF8文件时,总是转换不成功.提示: iconv: 未知 0 处的非法输入序列 后来使用 man iconv 查看,还是没发现异常,因为命令格式都是 ...

  6. UVA 11134 Fabled Rooks

    贪心+优先队列+问题分解 对x,y 分开处理 当 xl<cnt(当前处理行)时,不能简单的选择cnt,而是应该让xl=cnt 并重新加入优先队列.(y的处理同上) #include <io ...

  7. ICE-3.5.1-错误记录

    windwos上QT5使用ICE中遇到的一个小bug: error: C3083: “Stm”:“::”左侧的符号必须是一种类型error: C2039: “upCast”: 不是“IceProxy” ...

  8. webpack ------require,ensure

    require-ensure和require-amd的区别: require-amd 说明: 同AMD规范的require函数,使用时传递一个模块数组和回调函数,模块都被下载下来且都被执行后才执行回调 ...

  9. Delphi获取系统服务描述信息

    program Project1; {$APPTYPE CONSOLE} uses Windows, WinSvc; type SERVICE_DESCRIPTION = packed record ...

  10. C#调用C++DLL传递结构体数组的终极解决方案

    在项目开发时,要调用C++封装的DLL,普通的类型C#上一般都对应,只要用DllImport传入从DLL中引入函数就可以了.但是当传递的是结构体.结构体数组或者结构体指针的时候,就会发现C#上没有类型 ...