P3195 [HNOI2008]玩具装箱TOY(斜率优化dp)
设前缀和为$s[i]$
那么显然可以得出方程
$f[i]=f[j]+(s[i]-s[j]+i-j-L-1)^{2}$
换下顺序
$f[i]=f[j]+(s[i]+i-(s[j]+j+L+1))^{2}$
为了处理方便,我们套路地设
$a[i]=s[i]+i$
$b[i]=s[i]+i+L+1$
于是得出
$f[i]=f[j]+(a[i]-b[j])^{2}$
拆开:$f[i]=f[j]+a[i]^{2}-2*a[i]*b[j]+b[j]^{2}$
移项:$f[j]+b[j]^{2}=2*a[i]*b[j]+f[i]-a[i]^2$
于是我们就把不变量和变量分开了($i$固定)
仔细观察
$f[j]+b[j]^{2}=2*a[i]*b[j]+f[i]-a[i]^2$
$y=k*x+b$
一次函数!
$y=f[j]+b[j]^{2}$
$k=2*a[i]$($i$递增时,显然它是单调递增的)
$x=b[j]$
$b=f[i]-a[i]^{2}$
如果我们要让$f[i]$最小,就是让$b$最小
而对于每个$i$,$k$是不变的
那么问题就转化成:找到一个最优的$(x,y)$使$b$最小
考虑到$k$是单调递增的
于是我们就可以快乐地用单调队列维护下凸包辣
while(L<R&&K(h[L],h[L+])<=*a(i)) ++L;//显然h[L]不比h[L+1]优,可以删去
f[i]=f[h[L]]+(a(i)-b(h[L]))*(a(i)-b(h[L]));//计算出最优的f[i]
while(L<R&&K(h[R-],h[R])>K(h[R],i)) --R;//加入点(x[i],y[i])后,h[R]在凸包内部,可以删去①
h[++R]=i;//入队
①:显然在加入橙点后,蓝点在凸包内部,可以被删除

#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
typedef double db;
#define N 50005
db f[N],s[N];
int n,l,L,R,h[N];
inline db a(int x){return s[x]+x;}
inline db b(int x){return s[x]+x+l+;}
inline db X(int x){return b(x);}
inline db Y(int x){return f[x]+b(x)*b(x);}
inline db K(int x,int y){return (Y(x)-Y(y))/(X(x)-X(y));}
int main(){
scanf("%d%d",&n,&l);
for(int i=;i<=n;++i) scanf("%lf",&s[i]),s[i]+=s[i-];
L=R=;
for(int i=;i<=n;++i){
while(L<R&&K(h[L],h[L+])<=*a(i)) ++L;
f[i]=f[h[L]]+(a(i)-b(h[L]))*(a(i)-b(h[L]));
while(L<R&&K(h[R-],h[R])>K(h[R],i)) --R;
h[++R]=i;
}printf("%.0lf",f[n]);
return ;
}
P3195 [HNOI2008]玩具装箱TOY(斜率优化dp)的更多相关文章
- P3195 [HNOI2008]玩具装箱TOY 斜率优化dp
传送门:https://www.luogu.org/problem/P3195 题目描述 P教授要去看奥运,但是他舍不下他的玩具,于是他决定把所有的玩具运到北京.他使用自己的压缩器进行压缩,其可以将任 ...
- 洛谷P3195 [HNOI2008]玩具装箱TOY——斜率优化DP
题目:https://www.luogu.org/problemnew/show/P3195 第一次用斜率优化...其实还是有点云里雾里的: 网上的题解都很详细,我的理解就是通过把式子变形,假定一个最 ...
- BZOJ 1010: [HNOI2008]玩具装箱toy 斜率优化DP
1010: [HNOI2008]玩具装箱toy Description P教授要去看奥运,但是他舍不下他的玩具,于是他决定把所有的玩具运到北京.他使用自己的压缩器进行压缩,其可以将任意物品变成一堆,再 ...
- bzoj1010[HNOI2008]玩具装箱toy 斜率优化dp
1010: [HNOI2008]玩具装箱toy Time Limit: 1 Sec Memory Limit: 162 MBSubmit: 11893 Solved: 5061[Submit][S ...
- 【bzoj1010】[HNOI2008]玩具装箱toy 斜率优化dp
题目描述 P教授要去看奥运,但是他舍不下他的玩具,于是他决定把所有的玩具运到北京.他使用自己的压缩器进行压缩,其可以将任意物品变成一堆,再放到一种特殊的一维容器中.P教授有编号为1...N的N件玩具, ...
- P3195 [HNOI2008] 玩具装箱(斜率优化DP)
题目链接 设\(d[i]\)为将前 \(i\) 个玩具装入箱中所需得最小费用 容易得到动态转移方程: \[d[i] = min(d[j] + (s[i]-s[j]+i-j-1-L)^2), (j< ...
- [luogu3195 HNOI2008] 玩具装箱TOY (斜率优化dp)
题目描述 P教授要去看奥运,但是他舍不下他的玩具,于是他决定把所有的玩具运到北京.他使用自己的压缩器进行压缩,其可以将任意物品变成一堆,再放到一种特殊的一维容器中.P教授有编号为1...N的N件玩具, ...
- 洛谷P3195 [HNOI2008]玩具装箱TOY 斜率优化
Code: #include<cstdio> #include<algorithm> using namespace std; const int maxn = 100000 ...
- Bzoj 1010: [HNOI2008]玩具装箱toy(斜率优化)
1010: [HNOI2008]玩具装箱toy Time Limit: 1 Sec Memory Limit: 162 MB Description P教授要去看奥运,但是他舍不下他的玩具,于是他决定 ...
- 【BZOJ1010】【HNOI2008】玩具装箱toy (斜率优化DP) 解题报告
题目: 题目在这里 思路与做法: 这题不难想. 首先我们先推出一个普通的dp方程: \(f_i = min \{ f_j+(i-j-1+sum_i-sum_j-L)^2\}\) 然后就推一推式子了: ...
随机推荐
- js this指向理解
1.如果调用this的函数上级有多个对象,this只会指向上一级对象 下面实例fn函数调用this时,this指向b对象,如果b里面有a属性就输出值: 如果没有就是undefined 在来看下下面的实 ...
- 理解vue之element-ui中的 <template slot-scope="scope">
https://blog.csdn.net/tg928600774/article/details/81945140?utm_source=blogxgwz1
- PDO连接数据库-Xmodel
<?php/* * Copyright (c) 2018, 北京博习园教育科技有限公司 * All rights reserved. * * 文件名称: xmodel.php * 摘 要: 模型 ...
- archlinux 下使用 aria2+uget 作为下载工具
1.创建配置文件 sudo vim /etc/aria2/aria2.conf ## /etc/aria2/aria2.conf### '#'开头为注释内容, 选项都有相应的注释说明, 根据需要修改 ...
- 剑指offer——python【第44题】翻转单词顺序
题目描述 牛客最近来了一个新员工Fish,每天早晨总是会拿着一本英文杂志,写些句子在本子上.同事Cat对Fish写的内容颇感兴趣,有一天他向Fish借来翻看,但却读不懂它的意思.例如,“student ...
- PPT文件太大时可以考虑另存为PPTX格式
遇到一个PPT文件有24M,30多页,里面主要有一些图片. 使用自带的图片压缩功能进行压缩,发现没有什么改变,后来找了一些工具软件压缩,最多也只能减少22%. 后来另存为PPTX格式,减小到1.74M ...
- pytorch入门与实践-2.2
Tensor 1--本质上可以理解为具有不同维度的数组 2--支持的基本运算 |---创建Tensor: x=t.tensor(x,y) x,y 表示数组的大小 , x=t.rand(x,y), x ...
- AVL树C++实现(插入,删除,查找,清空,遍历操作)
AVL.h文件代码 #pragma once #include<iostream> #include<stack> #include <assert.h> usin ...
- Luogu 1309 - 瑞士轮 - [归并排序]
题目链接:https://www.luogu.org/problemnew/show/P1309 题解: 每次比赛前,每个人都是按照分数降序排好的,那么比赛完后,将选手按输赢分成两组,顺序依然按照原顺 ...
- PHP实现数组中每个字符出现次数最多的,并且如果两个字符出现相同,则在前面的先输出功能
$arr = ['a', 'b', 'a', 'e', 'g', 'g', 'a']; $count_per_values = array_count_values($arr); $res = []; ...