题面

​ 最近在搞dp, 发现自己的dp还是太弱了, 做的题比较少, 也有一些东西没学, 这道题算是我独立做的第一道斜率优化dp, 写篇题解纪念一下吧.

​ dp式比较简单, 就是一个线性的dp, 设\(f[i]\)为将1 ~ i分为若干个集合所花费的最小值, \(c[i]\)为1 ~ i的\(c\)值的前缀和, 对于满足\(j\)小于\(i\)的\(j\), 则有:

\[f[i] = min(f[j] + (c[i] - c[j] + i - j - 1 - l)^2)\tag{1}
\]

设\(a[i] = c[i] + i\), \(b[i] = c[i] + i + 1 + l\), 则可将上式化简为下式:

\[\begin{aligned}
f[i] = & min(f[j] + (a[i] - b[j])^2)\\
=&min(f[j] + a[i] ^ 2 + b[j] ^ 2 - 2 * a[i] * b[j])
\end{aligned}
\]

假设对于某个\(k\)(\(k\) >\(j\)), 选\(k\)比选\(j\)更优, 则有下式:

\[\begin{aligned}
f[k] + a[i] ^ 2 + b[k] ^ 2 - 2 * a[i] * b[k] &< f[j] + a[i] ^ 2 + b[j] ^ 2 - 2 * a[i] * b[j]\\
(f[k] + b[k] ^ 2) - (f[j] + b[j] ^ 2) &< 2 * a[i] * (b[k] - b[j])\\
\frac{(f[k] + b[k] ^ 2) - (f[j] + b[j] ^ 2)}{2 * (b[k] - b[j])} &< a[i]
\end{aligned}
\]

对于上述几个不等式, 由于\(c[i]\)与\(i\)单调递增, 所以\(a[i]\)也是单调递增的, 那么对于平面上的任意三个决策点\(j_1\), \(j_2\), \(j_3\), 若\(j_2\)对\(i\)最优, 则\((b[j_1], f[j_1] + b[j _ 1] ^ 2)\), \((b[j_2], f[j_2] + b[j _ 2]^2)\), \((b[j_3], f[j _ 3] + b[j _ 3] ^ 2)\)三点应该满足下列两个等式:

\[\begin{aligned}
\frac{(f[j_2] + b[j_2] ^ 2) - (f[j _ 1] + b[j _ 1] ^ 2)}{2 * (b[j_2] - b[j _ 1])} &< a[i]\\
\frac{(f[j_3] + b[j_3] ^ 2) - (f[j _ 2] + b[j _ 2] ^ 2)}{2 * (b[j_3] - b[j _ 2])} &\geq a[i]\\
\end{aligned}
\]

所以有:

\[\frac{(f[j_3] + b[j_3] ^ 2) - (f[j _ 2] + b[j _ 2] ^ 2)}{2 * (b[j_3] - b[j _ 2])} >\frac{(f[j_2] + b[j_2] ^ 2) - (f[j _ 1] + b[j _ 1] ^ 2)}{2 * (b[j_2] - b[j _ 1])}
\]

也就是斜率单调上升, 故维护一个下凸包即可, 注意单调队列初始化时要先加入一个0.

代码

#include <iostream>
#include <cstring>
#include <cstdio>
#define N 50005
#define int long long
using namespace std; int n, L, sum[N], a[N], b[N], f[N], q[N], l = 1, r; inline int read()
{
int x = 0, w = 1;
char c = getchar();
while(c < '0' || c > '9') { if (c == '-') w = -1; c = getchar(); }
while(c >= '0' && c <= '9') { x = x * 10 + c - '0'; c = getchar(); }
return x * w;
} bool F_check(int x, int y, int z) { return f[y] - f[x] + b[y] * b[y] - b[x] * b[x] < 2 * z * (b[y] - b[x]); } bool S_check(int x, int y, int z)
{
return (f[y] - f[x] + b[y] * b[y] - b[x] * b[x]) * (b[z] - b[y]) > (f[z] - f[y] + b[z] * b[z] - b[y] * b[y]) * (b[y] - b[x]);
} signed main()
{
n = read(); L = read();
for(int i = 1; i <= n; i++)
{
sum[i] = read(); sum[i] += sum[i - 1];
a[i] = sum[i] + i; b[i] = sum[i] + i + L + 1;
}
memset(f, 0x3f, sizeof(f));
b[0] = L + 1; f[0] = 0;
q[++r] = 0;
for(int i = 1; i <= n; i++)
{
while(l < r && F_check(q[l], q[l + 1], a[i])) l++;
f[i] = f[q[l]] + a[i] * a[i] + b[q[l]] * b[q[l]] - 2 * a[i] * b[q[l]];
while(l < r && S_check(q[r - 1], q[r], i)) --r;
q[++r] = i;
}
printf("%lld\n", f[n]);
return 0;
}
\\有一些数组的名字改动了一点点, 世上不是缺少不一样的东西, 而是缺少发现不一样的东西的眼睛

你觉得我会告诉你我在写题目之前就把题解写完了吗???

[luogu3198] 玩具装箱的更多相关文章

  1. BZOJ 1010: [HNOI2008]玩具装箱toy [DP 斜率优化]

    1010: [HNOI2008]玩具装箱toy Time Limit: 1 Sec  Memory Limit: 162 MBSubmit: 9812  Solved: 3978[Submit][St ...

  2. 【BZOJ-1010】玩具装箱toy DP + 斜率优化

    1010: [HNOI2008]玩具装箱toy Time Limit: 1 Sec  Memory Limit: 162 MBSubmit: 8432  Solved: 3338[Submit][St ...

  3. C++之路进阶——codevs1319(玩具装箱)

    1319 玩具装箱  时间限制: 1 s  空间限制: 128000 KB  题目等级 : 钻石 Diamond     题目描述 Description P教授要去看奥运,但是他舍不下他的玩具,于是 ...

  4. BZOJ 1010: [HNOI2008]玩具装箱toy 斜率优化DP

    1010: [HNOI2008]玩具装箱toy Description P教授要去看奥运,但是他舍不下他的玩具,于是他决定把所有的玩具运到北京.他使用自己的压缩器进行压缩,其可以将任意物品变成一堆,再 ...

  5. 【BZOJ】【1010】【HNOI2008】玩具装箱Toy

    DP/斜率优化 根据题目描述很容易列出动规方程:$$ f[i]=min\{ f[j]+(s[i]-s[j]+i-j-1-L)^2 \}$$ 其中 $$s[i]=\sum_{k=1}^{i} c[k] ...

  6. 【bzoj1010】[HNOI2008]玩具装箱toy

    1010: [HNOI2008]玩具装箱toy Time Limit: 1 Sec  Memory Limit: 162 MBSubmit: 9281  Solved: 3719[Submit][St ...

  7. 【斜率DP】BZOJ 1010:玩具装箱

    1010: [HNOI2008]玩具装箱toy Time Limit: 1 Sec  Memory Limit: 162 MBSubmit: 7537  Solved: 2888[Submit][St ...

  8. BZOJ_1010_[HNOI2008]_玩具装箱toy_(斜率优化动态规划+单调队列)

    描述 http://www.lydsy.com/JudgeOnline/problem.php?id=1010 给出\(n\)和\(l\).有\(n\)个玩具,第\(i\)个玩具的长度是\(c[i]\ ...

  9. 【BZOJ 1010】 [HNOI2008]玩具装箱toy (斜率优化)

    1010: [HNOI2008]玩具装箱toy Time Limit: 1 Sec  Memory Limit: 162 MBSubmit: 9330  Solved: 3739 Descriptio ...

随机推荐

  1. 通过这些示例快速学习Java lambda语法

    对于那些不熟悉函数式编程的人来说,基本的Java lambda语法起初可能有点令人生畏.但是,一旦将lambda表达式分解为它们的组成部分,语法很快就会变得有意义并变得非常自然. Java中lambd ...

  2. visual studio 2013 下ef6 CodeFirst 使用SQL Lite 数据库

    今天系统的来记录一下再vs2013下,使用ef6 codefirst功能,来操作SQL lite数据库 本来我以为sqlite数据库用的这么多,ef6肯定支持,结果,使用过程中很多坑,现在我把具体的配 ...

  3. Linux常用基本命令(more)

    more命令 作用:相比cat一次性显示文件内容,more用于分页显示内容,less比more更强大,大多数的参数类似 more [option] [file] -num : 每页显示num行 +nu ...

  4. mongodb ISODate问题(大量数据update优化)

    问题描述: 上周有个需求,把mongodb中birthday (ISO日期格式) 转换成北京时间,并保存成string类型. 最初思路: 遍历查找出的结果,逐个加8小时,然后通过_id逐个去updat ...

  5. luogu P4108 [HEOI2015]公约数数列——solution

    -by luogu 不会啊.... 然后%了一发题解, 关键是 考虑序列{$a_n$}的前缀gcd序列, 它是单调不升的,且最多只会改变$log_2N$次,因为每变一次至少除2 于是,当我们询问x时: ...

  6. js-ES6学习笔记-module(4)

    1.<script>标签打开defer或async属性,脚本就会异步加载.渲染引擎遇到这一行命令,就会开始下载外部脚本,但不会等它下载和执行,而是直接执行后面的命令. defer与asyn ...

  7. 语义SLAM的数据关联和语义定位(一)

    语义SLAM和多传感器融合是自动驾驶建图和定位部分比较热门的两种技术.语义SLAM中,语义信息的数据关联相较于特征点的数据关联有所不同.我们一般用特征描述子的相似性来匹配和关联不同图像中的特征点.特征 ...

  8. 在sublime text 3中让.vue文件的内容变成彩色

    直接上步骤: 1.按住ctrl + shift + p 2.输入install Package 3.输入Vue Syntax Highlight 执行完以上3步,再次打开.vue文件,会发现里面的内容 ...

  9. 绝版Node--Sequlize搭建服务(Node全栈之路 二)

    在Node全栈之路(一),也就是上篇文章中,我们讲到了sequlize的基本增删该查,这篇文章,我们在上篇文章的基础上继续探讨,讲一下关于sequlize创建的表之间的对应关系 参考资料:https: ...

  10. hashCode()与equals()方法的对比

        Java对于eqauls方法和hashCode方法是这样规定的: 1.如果两个对象相同,那么它们的hashCode值一定要相同: 2.如果两个对象的hashCode相同,它们并不一定相同(上面 ...