Building Bridges

题目大意

连接两根柱子 \(i,j\) 的代价是 \((h_i-h_j)^2+\sum\limits_{k=j+1}^{i-1}w_k\),连接具有传递性,求将 \(1,n\) 连接的最小代价。

思路分析

斜率优化 DP 板题。

设 \(f_i\) 表示考虑到前 \(i\) 根柱子并强制选择第 \(i\) 根柱子的最小代价,所求即 \(f_n\)。则容易列出状态转移方程:

\[f_i=\min_{j<i}(f_j+(h_i-h_j)^2+\sum_{k=j+1}^{i-1}w_k)
\]

设 \(s\) 为 \(w\) 的前缀和,即 \(s_i=\sum\limits_{j=1}^iw_j\),则方程可化为:

\[f_i=\min_{j<i}(f_j+h_i^2-2h_ih_j+h_j^2+s_{i-1}-s_{j})
\]

然后是斜率优化经典操作:

\[\begin{aligned}f_i&=f_j+h_i^2-2h_ih_j+h_j^2+s_{i-1}-s_{j}\\f_i-h_i^2-s_{i-1}&=f_j+h_j^2-s_j-2h_ih_j\\(f_i-h_i^2-s_{i-1})&=(-2h_j)(h_i)+(f_j+h_j^2-s_j)\end{aligned}
\]

设:

\[\begin{cases}y=f_i-h_i^2-s_{i-1}\\k=-2h_j\\x=h_i\\b=f_j+h_j^2-s_j\end{cases}
\]

问题转化为每次插入一条 \(k_i=-2h_i,b_i=f_i+h_i^2-s_i\) 的直线,查询 \(x_i=h_i\) 的最值,用李超线段树优化即可。

代码

自我感觉马蜂可看。

#include <iostream>
#include <cstring>
#include <cmath>
#include <cstdio>
#include <algorithm> using namespace std;
const int N=100100,V=1001000;
#define int long long
#define mid ((l+r)>>1)
#define inf 0x3f3f3f3f3f3f3f3f int n;
int h[N],s[N],f[N]; struct Line{
int k,b;
}line[N]; int calc(int id,int x){
return line[id].k*x+line[id].b;
} bool Less(int id1,int id2,int x){//比较优劣
return calc(id1,x)<calc(id2,x);
} struct ST{//简洁的李超线段树
int a[V<<2];
void add(int p,int l,int r,int id){
if(l==r){if(Less(id,a[p],l)) a[p]=id;return ;}
if(Less(id,a[p],mid)) swap(a[p],id);
if(Less(id,a[p],l)) add(p<<1,l,mid,id);
if(Less(id,a[p],r)) add(p<<1|1,mid+1,r,id);
}
int query(int p,int l,int r,int x){
int res=calc(a[p],x);
if(l==r) return res;
if(x<=mid) res=min(res,query(p<<1,l,mid,x));
else res=min(res,query(p<<1|1,mid+1,r,x));
return res;
}
}tree; signed main(){
scanf("%lld",&n);
for(int i=1;i<=n;i++) scanf("%lld",&h[i]);
for(int i=1;i<=n;i++){
scanf("%lld",&s[i]);
s[i]+=s[i-1];
}
line[0]={0,inf};//初始化第 0 条直线,保证空转移转移不到第 0 条上,也可以在 add 和 query 中特判空线段的情况,不过这样比较方便
line[1]=Line{-2*h[1],h[1]*h[1]-s[1]};//初始化第一条直线
tree.add(1,0,V,1);//加入第一条直线
for(int i=2;i<=n;i++){
f[i]=tree.query(1,0,V,h[i])+h[i]*h[i]+s[i-1];//查询,移项过去得 f[i]
line[i]=Line{-2*h[i],f[i]+h[i]*h[i]-s[i]};//新建直线
tree.add(1,0,V,i);//插入直线
}
cout<<f[n]<<'\n';
return 0;
}

Building Bridges 题解的更多相关文章

  1. 题解-[CEOI2017]Building Bridges

    [CEOI2017]Building Bridges 有 \(n\) 个桥墩,高 \(h_i\) 重 \(w_i\).连接 \(i\) 和 \(j\) 消耗代价 \((h_i-h_j)^2\),用不到 ...

  2. Luogu4655 [CEOI2017]Building Bridges

    Luogu4655 [CEOI2017]Building Bridges 有 \(n\) 根柱子依次排列,每根柱子都有一个高度.第 \(i\) 根柱子的高度为 \(h_i\) . 现在想要建造若干座桥 ...

  3. loj#2483. 「CEOI2017」Building Bridges 斜率优化 cdq分治

    loj#2483. 「CEOI2017」Building Bridges 链接 https://loj.ac/problem/2483 思路 \[f[i]=f[j]+(h[i]-h[j])^2+(su ...

  4. HDU 4584 Building bridges (水题)

    Building bridges Time Limit: 3000/1000 MS (Java/Others)    Memory Limit: 65535/32768 K (Java/Others) ...

  5. ceoi2017 Building Bridges(build)

    Building Bridges(build) 题目描述 A wide river has nn pillars of possibly different heights standing out ...

  6. LOJ 2483: 洛谷 P4655: 「CEOI2017」Building Bridges

    题目传送门:LOJ #2483. 题意简述: 有 \(n\) 个数,每个数有高度 \(h_i\) 和价格 \(w_i\) 两个属性. 你可以花费 \(w_i\) 的代价移除第 \(i\) 个数(不能移 ...

  7. POJ2749:Building roads——题解

    http://poj.org/problem?id=2749 (这个约翰的奶牛真多事…………………………) i表示u与s1连,i+n表示u与s2连. 老规矩,u到v表示取u必须取v. 那么对于互相打架 ...

  8. 洛谷 P2872 [USACO07DEC]道路建设Building Roads 题解

    P2872 [USACO07DEC]道路建设Building Roads 题目描述 Farmer John had just acquired several new farms! He wants ...

  9. Design Tip #142 Building Bridges

    http://www.kimballgroup.com/2012/02/design-tip-142-building-bridges/ The dominant topologies of Data ...

  10. loj#2483. 「CEOI2017」Building Bridges(dp cdq 凸包)

    题意 题目链接 Sol \[f[i], f[j] + (h[i] - h[j])^2 + (w[i - 1] - w[j]))\] 然后直接套路斜率优化,发现\(k, x\)都不单调 写个cdq就过了 ...

随机推荐

  1. PHP生成随机中文姓名

    <?phpfunction &xingming(){ for ($i = 0; $i < 1; $i++) { $xing = "赵,钱,孙,李,周,吴,郑,王,冯,陈, ...

  2. ASL单芯片CS5366TypeC转HDMI4K60HZ加HUB多口方案|CS5366带PD拓展方案原理图

    CS5366芯片是ASL集睿致远最新推出的2Len带PD的扩展坞方案芯片,CS5366支持4K60HZ. 在分辨率4K下,刷新率60HZ对于30HZ看似提升不多,但是对于应用在游戏主座的客户来说至关重 ...

  3. 每日一题 力扣 445 https://leetcode.cn/problems/add-two-numbers-ii/

    可以直接用栈去做就行,逆序想到栈的做法 然后算完一个就直接赋值给答案数组  我用的是常见 public ListNode addTwoNumbers(ListNode l1, ListNode l2) ...

  4. 【转载】Linux虚拟化KVM-Qemu分析(二)之ARMv8虚拟化

    原文链接: 作者:LoyenWang 出处:https://www.cnblogs.com/LoyenWang/ 公众号:LoyenWang 版权:本文版权归作者和博客园共有 转载:欢迎转载,但未经作 ...

  5. CS144 LAB5~LAB6

    CS144 lab5~6 最后两个lab了,虽然很多大佬都说剩下的两个lab比起TCP的实现,"简直太简单了",但是我认为做这两个之前需要补充一些额外的网络知识,不然直接上手去做的 ...

  6. happens-before 原则

    happens-before 简述 从 JDK 5 开始,Java 使用新的 JSR-133 内存模型.JSR-133 使用 happens-before 的概念来阐述操作之间的内存可见性.在 JMM ...

  7. 你不知道的 HTTP Referer

    前言 上周突然发现自己的自己站点的图片全都403了,之前还是好好的,图片咋就全都访问不了呢?由于我每次发文章都是先发了掘金,然后再从掘金拷贝到我自己的站点,这样我就不用在自己的站点去上传图片了,非常方 ...

  8. python: ImportError: cannot import name '_unicodefun' from 'click'

    报错 报错原因 click模块版本问题 解决方案 指定click版本为8.0.4 参考链接 https://github.com/psf/black/issues/2964

  9. sudo提权操作

    sudo提权操作 sudo sudo是linux系统管理指令,是允许系统管理员让普通用户执行一些或者全部的root命令的一个工具,如halt,reboot,su等等.这样不仅减少了root用户的登录 ...

  10. Datahub稳定版本0.10.4安装指南(独孤风版本)

    大家好,我是独孤风,大数据流动的作者. 曾几何时,我在第一次安装JDK环境的时候也遇到了不小的麻烦,当时还有朋友就因为这个环境问题觉得自己根本不是编程的料,选择了放弃.当时有个段子说,"如果 ...