当前位置: 首页 > news >正文

[HNOI2008]玩具装箱toy

Description

BZOJ1010

Solution

斜率优化DP首题,多写一点吧。

Step 1 写出DP方程

\(f_i\)\(i\)点时的最优方案,\(s_i\)\(i\)\(C_i\)前缀和,则有\(f_i = min\{f_j+(i-j-1+s_i-s_j-l)^2\mid 0\le j < i-1\}\)

Step 2 证明决策单调性

不要被这个“决策单调性”给唬住,其实就是证明:若在计算\(f_i\)的时候,选\(j\)比选\(k\)好,那么之后永远都有选\(j\)比选\(k\)好。

证明:
首先设\(t_x = s_x+x,c = l+1\)\(j > k\),选\(j\)比选\(k\)好,简化之后的表示
\(f_j+(t_i-t_j-c)^2 < f_k + (t_i-t_j-c)^2\)
\(\Leftrightarrow f_j+t_i^2+t_j^2+c^2-2t_it_j+2t_jc-2t_ic < f_k+t_i^2+t_k^2+c^2-2t_it_k+2t_kc-2t_ic\)
\(\Leftrightarrow f_j+t_j^2-2t_it_j+2t_jc - f_k - t_k^2 + 2t_it_k - 2t_kc < 0\)
\(\Leftrightarrow f_j + t_j^2+ 2t_jc - f_k - t_k^2 - 2t_kc < 2t_it_j - 2t_it_k\)
由于\(t\)是单调上升的,所以\(2t_j-2t_k>0\),所以
\(\mbox{原式}\Leftrightarrow \displaystyle\frac{f_j + t_j^2+ 2t_jc - f_k - t_k^2 - 2t_kc}{2t_j - 2t_k} < t_i\)
又因为\(t\)是单调上升的,所以一旦满足了这个条件,选\(j\)永远比选\(k\)好。

Step 3 构造斜率形式

这一步其实就是看分子分母,化出和\(j\)\(k\)有关的式子,就可以了。

\(F_x = t_x^2+f_x+2ct_x\)\(G_x=2t_x\)
则原式可化成\(\displaystyle\frac{F_j-F_k}{G_j-G_k}<t_i\),由于\(G\)单调增,不等号左边的式子(上下同乘\(-1\)后)就是在平面\(GOF\)上的一条直线\((k,j)\)的斜率(记为\(K_{k,j}\))。

Step 4 证明斜率单调

\(x, y, z\)满足\(x < y < z\),且\(K_{x,y}>K_{y,z}\),则选\(y\)不可能更优。

证明:考虑反证法,若\(y\)优于\(x\)\(z\),则有:
\(\displaystyle\frac{F_z-F_y}{G_z-G_y}>t_i\)(这个式子其实是将Step2中的\(j>k\)反过来推出来的)
\(\displaystyle\frac{F_y-F_x}{G_y-G_x}<t_i\)
\(K_{y,z}=\displaystyle\frac{F_z-F_y}{G_z-G_y}>\displaystyle\frac{F_y-F_x}{G_y-G_x}=K_{x,y}\)与题设矛盾。

这里应该先考虑\(y\)优于\(x\)\(z\),推出式子后得出斜率的单调结论。

Step 5 单调队列优化DP

单调队列是一个双端队列。

由于Step2,3,若在\(i\)处有\(K_{k,j}<t_i\)(\(k, j\)位于队首),则应该令\(k\)出队,反复执行直至队列中只有一个元素或不满足条件为止,此时队首即为决策。

当计算出\(f_i\)后,利用Step4的结论,在队尾不断出队直至直至队列中只有一个元素或不满足条件为止,并将\(i\)放入队尾。

Code

#include <cstdio>
#include <cmath>

typedef long long LL;
const int N = 50000 + 10;
const double eps = 1e-10;

int n, l;
LL C[N], f[N], s[N], t[N], c, F[N], G[N];
int q[N], qhd, qtl;

inline double K(int x, int y) {
    return 1.0 * (F[x] - F[y]) / (G[x] - G[y]); 
}

inline int dcmp(double x) {
    if (fabs(x) < eps) return 0;
    else if (x < 0) return -1;
    else return 1;
}

int main () {
    // input
    scanf("%d%d", &n, &l);
    for (int i = 1; i <= n; ++i) scanf("%lld", &C[i]);
    // init
    c = l + 1;
    for (int i = 1; i <= n; ++i) {
        s[i] = s[i-1] + C[i];
        t[i] = s[i] + i;
        G[i] = 2 * t[i];
    }
    // dp 
    f[0] = 0;
    q[qtl++] = 0;
    for (int i = 1; i <= n; ++i) {
        while (qhd < qtl - 1) {
            if (dcmp(K(q[qhd], q[qhd+1]) - t[i]) == -1) qhd++;
            else break;
        }
        int j = q[qhd];
        f[i] = f[j] + (t[i] - t[j] - c) * (t[i] - t[j] - c);
        F[i] = t[i] * t[i] + f[i] + 2 * c * t[i];  // mark
        while (qhd < qtl - 1) {
            if (dcmp(K(q[qtl-1], q[qtl-2]) - K(q[qtl-1], i)) == 1) qtl--;
            else break;
        }
        q[qtl++] = i;
    }   
    printf("%lld\n", f[n]);
    return 0;
}

Note

这个题是我写的斜率优化DP的第一题,感觉斜率优化很模板化,只需要一点点推就行了,要注意的一点是斜率优化的复杂度\(O(n)\)的,另外,演草时要好好写字,否则真的会看不清...(例如mark处我一开始写的是+t[i]

转载于:https://www.cnblogs.com/wyxwyx/p/bzoj1010.html

相关文章:

  • pjsip uri demo
  • 【git】git入门之把自己的项目上传到github
  • LAMP架构(PHP5安装,PHP7安装)
  • 爬虫 大规模数据 采集心得和示例
  • RemoTing 搭建简单实现
  • CentOS中利用Docker安装RabbitMQ
  • MySQL DBA技术难度低为什么工资比Oracle高?
  • Kubernetes中StatefulSet介绍
  • Flutter 中的 Animations(二)
  • Spring Cloud Commons 普通抽象
  • zabbix中文问题汇总
  • join
  • 华为S5300系列交换机V200R001SPH027升级补丁
  • 正则表达式小结
  • sql查询语句
  • ES6 ...操作符
  • JavaScript 基本功--面试宝典
  • Linux编程学习笔记 | Linux IO学习[1] - 文件IO
  • MySQL QA
  • Redis字符串类型内部编码剖析
  • Spring Boot MyBatis配置多种数据库
  • SwizzleMethod 黑魔法
  • vue2.0一起在懵逼的海洋里越陷越深(四)
  • webpack+react项目初体验——记录我的webpack环境配置
  • 对JS继承的一点思考
  • 免费小说阅读小程序
  • 详解NodeJs流之一
  • 自制字幕遮挡器
  • 走向全栈之MongoDB的使用
  • ​猴子吃桃问题:每天都吃了前一天剩下的一半多一个。
  • #define 用法
  • #HarmonyOS:Web组件的使用
  • (1)STL算法之遍历容器
  • (39)STM32——FLASH闪存
  • (C语言)共用体union的用法举例
  • (DenseNet)Densely Connected Convolutional Networks--Gao Huang
  • (Redis使用系列) Springboot 整合Redisson 实现分布式锁 七
  • (vue)页面文件上传获取:action地址
  • (附源码)spring boot校园拼车微信小程序 毕业设计 091617
  • (附源码)springboot“微印象”在线打印预约系统 毕业设计 061642
  • (论文阅读30/100)Convolutional Pose Machines
  • (转)GCC在C语言中内嵌汇编 asm __volatile__
  • (转)setTimeout 和 setInterval 的区别
  • (轉)JSON.stringify 语法实例讲解
  • (自适应手机端)响应式新闻博客知识类pbootcms网站模板 自媒体运营博客网站源码下载
  • .bat批处理出现中文乱码的情况
  • .net core 6 使用注解自动注入实例,无需构造注入 autowrite4net
  • .Net Core和.Net Standard直观理解
  • .NET关于 跳过SSL中遇到的问题
  • /usr/local/nginx/logs/nginx.pid failed (2: No such file or directory)
  • @ModelAttribute注解使用
  • [ 第一章] JavaScript 简史
  • [30期] 我的学习方法
  • [Apio2012]dispatching 左偏树
  • [BZOJ 2142]礼物(扩展Lucas定理)