二叉搜索树 [四边形不等式优化区间dp]

题目描述

有 \(n\) 个结点,第 \(i\) 个结点的权值为 \(i\) 。

你需要对它们进行一些操作并维护一些信息,因此,你需要对它们建立一棵二叉搜索树。在整个操作过程中,第i个点需要被操作 \(x_i\) 次,每次你需要从根结点一路走到第 \(i\) 个点,耗时为经过的结点数。最小化你的总耗时。

输入格式

第一行一个整数 \(n\) ,第二行 \(n\) 个整数 \(x_1\to x_n\)。

输出格式

一行一个整数表示答案。

样例

样例输入

5
8 2 1 4 3

样例输出

35

数据范围与提示

对于 \(10\%\) 的数据,\(n\leqslant 10\)。

对于 \(40\%\) 的数据,\(n\leqslant 300\)。

对于 \(70\%\) 的数据,\(n\leqslant 2000\)。

对于 \(100\%\) 的数据,\(n\leqslant 5000,1\leqslant x_i\leqslant 10^9\)。

提示:二叉搜索树或者是一棵空树,或者是具有下列性质的二叉树:若它的左子树不空,则左子树上所有结点的值均小于它的根结点的值;若它的右子树不空,则右子树上所有结点的值均大于它的根结点的值;它的左、右子树也分别为二叉搜索树。

分析

第一眼看上去发现自己不会建二叉排序树了,直接写暴力……,仔细想一想,二叉排序树的性质就是左子树都比根小,右子树都比根大,那么就可以把大区间 \([L,R]\) 通过根节点 \(k\) 分成两部分,然后这里就是一个几乎是裸的区间 \(dp\) 的板子了。

在更新 \(f[i][j]\) 的时候,因为 \([i,j]\) 这一段之间的每个节点都要多经过一个节点,所以要加上整棵树的值,而这用前缀和就可以维护。完结!

代码

#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#define re register
using namespace std;
#define ll long long
const int maxn = 5e3+10;
ll f[maxn][maxn];
int g[maxn][maxn];
ll sum[maxn];
int a[maxn];
inline ll read(){//快读
ll s = 0,f = 1;
char ch = getchar();
while(!isdigit(ch)){if(ch == '-')f = -1;ch = getchar();}
while(isdigit(ch)){s=s*10+ch-'0';ch = getchar();}
return s * f;
}
int main(){
freopen("D.in","r",stdin);
freopen("D.out","w",stdout);
ll n = read();
for(re int i = 1;i<=n;++i){//预处理
a[i] = read();
f[i][i] = a[i];//记录值
g[i][i] = i;//记录决策点(四边形不等式优化)
sum[i] = sum[i-1] + a[i];//前缀和
}
//以下是区间dp
for(re int l = n-1;l >= 1;--l){
for(re int r = l+1;r <= n;++r){
f[l][r] = 0x3f3f3f3f3f3f3f3f;//初始化极大值
for(int k=g[l][r-1];k<=g[l+1][r];++k){
if(f[l][r] > f[l][k-1] + f[k+1][r] + sum[r]-sum[l-1]){
f[l][r] = f[l][k-1] + f[k+1][r] + sum[r]-sum[l-1];//向上更新答案
g[l][r] = k;//记录决策点
}
}
}
}
printf("%lld\n",f[1][n]);//输出最后的答案
return 0;
}

二叉搜索树 [四边形不等式优化区间dp]的更多相关文章

  1. hdu 3480 Division(四边形不等式优化)

    Problem Description Little D is really interested in the theorem of sets recently. There’s a problem ...

  2. 剑指 Offer 33. 二叉搜索树的后序遍历序列

    剑指 Offer 33. 二叉搜索树的后序遍历序列 输入一个整数数组,判断该数组是不是某二叉搜索树的后序遍历结果.如果是则返回 true,否则返回 false.假设输入的数组的任意两个数字都互不相同. ...

  3. 二叉搜索树TREE(线段树,区间DP)

    前言 线段树+区间DP题,线段树却不是优化DP的,是不是很意外? 题面 二叉搜索树是一种二叉树,每个节点都有一个权值,并且一个点的权值比其左子树里的点权值都大,比起右子树里的点权值都小. 一种朴素的向 ...

  4. 区间dp之四边形不等式优化详解及证明

    看了那么久的四边形不等式优化的原理,今天终于要写一篇关于它的证明了. 在平时的做题中,我们会遇到这样的区间dp问题 它的状态转移方程形式一般为dp[i][j]=min(dp[i][k]+dp[k+1] ...

  5. HDU 2829 区间DP & 前缀和优化 & 四边形不等式优化

    HDU 2829 区间DP & 前缀和优化 & 四边形不等式优化 n个节点n-1条线性边,炸掉M条边也就是分为m+1个区间 问你各个区间的总策略值最少的炸法 就题目本身而言,中规中矩的 ...

  6. 区间DP石子合并问题 & 四边形不等式优化

    入门区间DP,第一个问题就是线性的规模小的石子合并问题 dp数组的含义是第i堆到第j堆进行合并的最优值 就是说dp[i][j]可以由dp[i][k]和dp[k+1][j]转移过来 状态转移方程 dp[ ...

  7. CSP 201612-4 压缩编码 【区间DP+四边形不等式优化】

    问题描述 试题编号: 201612-4 试题名称: 压缩编码 时间限制: 3.0s 内存限制: 256.0MB 问题描述: 问题描述 给定一段文字,已知单词a1, a2, …, an出现的频率分别t1 ...

  8. 区间dp+四边形不等式优化

    区间dp+四边形优化 luogu:p2858 题意 给出一列数 \(v_i\),每天只能取两端的数,第 j 天取数价值为\(v_i \times j\),最大价值?? 转移方程 dp[i][j] :n ...

  9. 【非原创】codeforces 1025D - Recovering BST【区间dp+二叉搜索树】

    题目:戳这里 题意:给一个不下降序列,有n个数.问能否构造一个二叉搜索树,满足父亲和儿子之间的gcd>1. 解题思路:其实这题就是构造个二叉搜索树,只不过多了个条件.主要得了解二叉搜索树的性质, ...

随机推荐

  1. 解决nginx在Linux中已经正常启动,Windows端的浏览器却无法访问的问题

    一:查看Linux中nginx已经正常启动 二:查看80端口,未被占用 三:检查防火墙的问题 关闭防火墙:chkconfig iptables off //失败 暂时关闭防火墙:service ipt ...

  2. 高阶Pandas知识图谱-《利用Python进行数据分析》

    所有内容整理自<利用Python进行数据分析>,使用MindMaster Pro 7.3制作,emmx格式,源文件已经上传Github,需要的同学转左上角自行下载或者右击保存图片. 其他章 ...

  3. DJANGO-天天生鲜项目从0到1-002-用户模块-注册

    本项目基于B站UP主‘神奇的老黄’的教学视频‘天天生鲜Django项目’,视频讲的非常好,推荐新手观看学习 https://www.bilibili.com/video/BV1vt41147K8?p= ...

  4. .net 面试题 2020-2-26

    2020-2-26 每日几道面试题1. .NET和C#有什么区别答:.NET一般指 .NET FrameWork框架,它是一种平台,一种技术.C#是一种编程语言,可以基于.NET平台的应用. 2.一列 ...

  5. LQB2018A09倍数问题

    这个题,第一反应一定是三个for嵌套加一个max比较. 超级无敌大暴搜 #include <iostream> #include <string> #include <s ...

  6. sscanf,sprintf(思修课的收获)

    转载的,就是做个笔记 sprintf函数原型为 int sprintf(char *str, const char *format, ...).作用是格式化字符串,具体功能如下所示: (1)将数字变量 ...

  7. express,node.js实现获取本地文件夹下面的全部图片文件

    http://www.luyixian.cn/javascript_show_169354.aspx 按照网上的教程试了多次,处理了各种结果后还有报错, 最后的报错是cant find module ...

  8. 菜鸟教程的 mysql-connector 基础

    安装驱动 python -m pip install mysql-connector 导包 import mysql.connector mydb = mysql.connector.connect( ...

  9. Django学习路6_修改数据库为 mysql ,创建mysql及进行迁徙

    在项目的 settings 中修改 DATABASES = { 'default': { # 'ENGINE': 'django.db.backends.sqlite3', # 'NAME': os. ...

  10. PHP decoct() 函数

    实例 把十进制转换为八进制: <?phpecho decoct("30") . "<br>";echo decoct("10&quo ...