P3195 [HNOI2008]玩具装箱

P3195 [HNOI2008]玩具装箱

题意:

n件玩具,第i件玩具经过压缩后的一维长度为CiC_iCi,现在把玩具装入一维容器中,要求:

  1. 在一个一维容器中的玩具编号是连续的
  2. 如果一个一维容器中有多个玩具,那么两件玩具之间要加入一个单位长度的填充物。

制作容器的费用与容器的长度有关。如果容器长度为x,其制作费用为(x−L)2(x-L)^2(xL)2.
问所有容器的总费用最小是多少

题解:

斜率优化dp入门题
前置知识:
需要会单调队列优化

当dp方程为dp[i]=a[i]+b[i]时,这个方程是O(n2)O(n^2)O(n2)
此时可以用单调队列将其优化为O(n)
当dp方程为dp[i]=a[i]*b[j]+c[i]+d[j]时,因为存在a[i]*b[j]这个即有i又有j的项,此时单调队列不好用,就需要使用斜率优化

回到本题:
这个题的转移方程很好写:
sum[i]表示前i件玩具的长度和
dp[i]表示把前i件玩具装进容器所需要的最小费用
dp[i]=min(dp[j]+((sum[i]−sum[j])+(i−j−1)−L)2)(j<i)dp[i]=min(dp[j]+((sum[i]-sum[j])+(i-j-1)-L)^2)(j<i)dp[i]=min(dp[j]+((sum[i]sum[j])+(ij1)L)2)(j<i)
不过转移显然是O(n2)O(n^2)O(n2)的,因此需要进行优化:
我们设a[i]=sum[i]+i,b[j]=sum[j]+j+L+1(就是将i和j的式子分开,a只与i有关,b只与j有关)
则:dp[i]=dp[j]+(a[i]−b[j])2dp[i]=dp[j]+(a[i]-b[j])^2dp[i]=dp[j]+(a[i]b[j])2
展开有:
dp[i]=dp[j]+a[i]2−2∗a[i]∗b[j]+b[j]2dp[i]=dp[j]+a[i]^2-2*a[i]*b[j]+b[j]^2dp[i]=dp[j]+a[i]22a[i]b[j]+b[j]2
移项有:
dp[j]+b[j]2=2∗a[i]∗b[j]+dp[i]−a[i]2dp[j]+b[j]^2=2*a[i]*b[j]+dp[i]-a[i]^2dp[j]+b[j]2=2a[i]b[j]+dp[i]a[i]2
a[i]=sum[i]+i,而sum是可以算出来的,也就是说a[]是可以预处理出来的,我们可以当作是常数
那么这个式子我们就可以认为:
是一条斜率为2∗a[i]2*a[i]2a[i]的直线,解决为dp[i]−a[i]2dp[i]-a[i]^2dp[i]a[i]2
在这里插入图片描述
此时dp[i]的含义就是:当上述直线过点(b[j],dp[j]+b[j]2)(b[j],dp[j]+b[j]^2)(b[j],dp[j]+b[j]2)时,直线在y轴的截距为dp[i]+a[i]2dp[i]+a[i]^2dp[i]+a[i]2
现在我们要求的就是这个截距的最小值
直线的斜率为2∗a[i]2*a[i]2a[i]是递增的,由此可以联想到凸包,凸包中相邻两点的斜率是单调递增的
由下面的图像可知,满足条件的最优的点PjP_jPj为第一个slope(Pj,Pj+1)>2∗a[i]slope(P_j,P_{j+1})>2*a[i]slope(Pj,Pj+1)>2a[i]的点
slope表示斜率
在这里插入图片描述
再看这个图:如果维护凸包,一定时弹掉B,为什么?如果一条直线斜率大于GC的直线从下面平移上来,一定会到C这里停下。如果是一条斜率小于GC大于FG的,显然会在G停下来,B注定要被舍弃,这就是为什么要维护凸包。
在这里插入图片描述

因此我们用单调队列来优化这个凸包:

设队首为head,队尾为tail:

  1. 对队首
    while(slope(Phead,Phead+1)<2∗a[i])head++while(slope(P_{head},P_{head+1})<2*a[i])~~head++while(slope(Phead,Phead+1)<2a[i])  head++
    当斜率小于2a[i]时,弹出队首
  2. 此时队首的点即为最优,根据它计算出dp[i]
  3. 对队尾:
    while(slope(Ptail−1,Ptail)>slope(Ptail,Pi))tail−−while(slope(P_{tail-1},P_{tail})>slope(P_{tail},P_i))~~tail--while(slope(Ptail1,Ptail)>slope(Ptail,Pi))  tail
  4. 在队尾插入PiP_iPi

初始化时要加入单调队列的点为P0而不是P1初始化时要加入单调队列的点为P_0而不是P_1P0P1
在这里我们总结一下,单调队列斜率优化的步骤:
1.弹队头,就是最左边的点.
2.放直线,算答案,得到当前状态的答案,得到新的待加入的点.
3.弹队尾,把插入新点之后不合法的点弹掉.最后加入新点就好了.

代码:

#include <cmath>
#include <cstdio>
#include <iostream>
#define maxn 50005
#define ll long long
using namespace std;
int q[maxn];
double A[maxn], B[maxn], dp[maxn], sum[maxn];
double X(int x)
{return B[x];
}
double Y(int x)
{return dp[x] + B[x] * B[x];
}
double slope(int a, int b)
{return (Y(a) - Y(b)) / (X(a) - X(b));
}
int main()
{int n, l;cin >> n >> l;for (int i= 1; i <= n; i++)scanf("%lf", &sum[i]);for (int i= 1; i <= n; i++) {sum[i]+= sum[i - 1];A[i]= sum[i] + i;B[i]= sum[i] + i + l + 1;}B[0]= l + 1; //B[0]=sum[0]+0+l+1=l+1int tail= 1, head= 1;for (int i= 1; i <= n; i++) {while (head < tail && slope(q[head], q[head + 1]) < 2 * A[i]) //如果队首不符合要求弹出head++;int j= q[head];dp[i]= dp[j] + (A[i] - B[j]) * (A[i] - B[j]); //进行状态转移//舍去不合格点,加入新点while (head < tail && slope(i, q[tail - 1]) < slope(q[tail - 1], q[tail]))tail--;q[++tail]= i;}printf("%lld", (ll)dp[n]);return 0;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/315907.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

卷积与莫比乌斯反演

卷积与莫比乌斯反演 目录 卷积与莫比乌斯反演 0前言 0.1前置技能 0.2问题的引入 1.简单定义 1.1数论函数的定义 1.2卷积的定义 1.3反演的基本形式 2.1莫比乌斯反演 3.1例题&#xff1a;【luogu-P2257 YY的GCD】 题目大意&#xff1a; solution1 solution2 0.前言 莫比…

ML.NET机器学习、API容器化与Azure DevOps实践(三):RESTful API

通过上文所述案例&#xff0c;我们已经选择了最优回归算法来预测学生的综合成绩&#xff0c;并且完成了基于训练数据集的预测模型训练。从实现上&#xff0c;训练好的模型被保存成一个ZIP文件&#xff0c;以便在其它项目中直接调用以完成机器学习的实践场景。在本文中&#xff…

杜教筛

杜教筛 1.概述 杜教筛是用以解决积性函数前缀和的算法。 在学习了莫比乌斯反演之后&#xff0c;杜教筛的过程就会显得简单而自然。 2.基本形式 对于积性函数&#xff0c;我们定义如下函数&#xff1a; 构造积性函数 &#xff0c;使得 显然 &#xff1a; 进一步转化&#xf…

ML.NET机器学习、API容器化与Azure DevOps实践(二):案例

在上文中&#xff0c;我简单地介绍了机器学习以及ML.NET的相关知识&#xff0c;从本讲开始&#xff0c;我会基于一个简单的案例&#xff1a;学生成绩预测&#xff0c;来介绍使用ML.NET进行机器学习以及API部署的基本过程。本案例的数据来源为加州大学尔湾分校的机器学习公开样本…

业界萌新对斯坦纳树的小结

业界萌新对斯坦纳树的小结 0.简介 斯坦纳树问题是组合优化问题&#xff0c;与最小生成树相似&#xff0c;是最短网络的一种。最小生成树是在给定的点集和边中寻求最短网络使所有点连通。而最小斯坦纳树允许在给定点外增加额外的点&#xff0c;使生成的最短网络开销最小。 ——…

cf1208E. Let Them Slide

cf1208E. Let Them Slide 题意&#xff1a; 都放在一个长度为W的框里面。有n个序到&#xff0c;第i个序列的长度是1。这些序到并排放在一起&#xff0c;每一个序列都放在一个长度为w的框里 这些序列可以在框里面滑动&#xff0c;但是不能划出框。 对于每一个位置&#xff0…

结合eShopOnWeb全面认识领域模型架构

一.项目分析在上篇中介绍了什么是"干净架构"&#xff0c;DDD符合了这种干净架构的特点&#xff0c;重点描述了DDD架构遵循的依赖倒置原则&#xff0c;使软件达到了低藕合。eShopOnWeb项目是学习DDD领域模型架构的一个很好案例&#xff0c;本篇继续分析该项目各层的职…

SOS_dp算法

Codeforces博客 简介&#xff1a; 前置知识&#xff1a;状压dp Sum over Subsets dynamic programming&#xff0c;简称Sos dp,状压dp的一种 用一个列题引出SOS dp&#xff1a; 给你一个由2N2^N2N个整数组成的确定数组A&#xff0c;我们需要计算对于任意的x&#xff0c;F(x)所…

微软开源Bing搜索背后的关键算法

微软今天宣布开源了一项 Bing 搜索背后的关键算法 —— SPTAG&#xff0c;它使 Bing 能够快速将搜索结果返回给用户。仅在几年前&#xff0c;网络搜索很简单&#xff0c;用户输入几个关键词然后浏览结果页面。现如今&#xff0c;这些用户可能会在手机上拍照并将其放入搜索框中&…

Stern-Brocot Tree

Stern-Brocot Tree 0.简介 Stern-Brocot Tree&#xff0c;俗称SB树&#xff08;滑稽&#xff09;。它能够表示出所有的最简分数&#xff0c;如下图。 1.一些规律 显然&#xff0c;对于两个相邻的最简分数 可以得到另一个最简分数 这样就可以在Stern-Brocot Tree上表示出所有…

FWT(快速沃尔什变换)

文章目录引入&#xff1a;or卷积and卷积xor卷积IFWT模板&#xff1a;例题&#xff1a;引入&#xff1a; FFT/NTT是用来解决∑ijkA[i]B[j]\sum_{ijk}A[i]B[j]∑ijk​A[i]B[j]的式子 而FWT是用来解决Ci∑j⊕kiAjBkC_i\sum_{j⊕ki}A_jB_kCi​∑j⊕ki​Aj​Bk​ ​ FWT是一种用于处…

教你自制.NET Core Global Tools

点击上方蓝字关注“汪宇杰博客”命令行是程序员装逼利器&#xff0c;.NET Core也可以写命令行程序&#xff0c;但是如何分发给其他程序员使用&#xff0c;一直是个问题。现在&#xff0c;有了.NET Core Global Tools&#xff0c;可以很方便的解决分发问题&#xff0c;我们来看看…

三点间LCA

三点间LCA 1.直接上题——jzoj5883. 【NOIP2018模拟A组9.25】到不了 Dscription wy 和 wjk 是好朋友。 今天他们在一起聊天&#xff0c;突然聊到了以前一起唱过的《到不了》。 “说到到不了&#xff0c;我给你讲一个故事吧。” “嗯&#xff1f;” “从前&#xff0c;神和凡人…

微软拥抱开源,Win10为啥要引入真Linux4.X内核?

来源 | 异步 | 文末赠书2019 年微软 Build 开发者大会在雷德蒙德召开。继将 Bash shell、原生 OpenSSH、WSL 引入 Windows&#xff0c;以及在微软商店提供 Ubuntu、SUSE Linux 和 Fedora 等发行版&#xff0c;微软又宣布了一个重大的决定 —— 将完整的 Linux 内核引入 Windows…

F.孤独(牛客小白月赛39)

F.孤独&#xff08;牛客小白月赛39&#xff09; 题意&#xff1a; 给定一棵树&#xff0c;寻找一个路径&#xff0c;将断掉所有与这个路径上的点相连的边&#xff0c;使得剩下的最大连通块的大小最小 题解&#xff1a; 这题有点印象&#xff0c;感觉做过&#xff0c;至少这…

分布式 - 分布式系统的特点

20世纪60年代&#xff0c;IBM研发了System 360架构大型机&#xff0c;与同时期的波音707、福特汽车誉为商业三大成就&#xff0c;凭借其卓越的性能和良好的稳定性&#xff0c;开启了大型机的时代&#xff0c;诞生了非常多的集中式系统&#xff0c;采用单机架构&#xff0c;有非…

[WC2011][BZOJ2115] Xor

BZOJ2115 Xor 题目描述&#xff1a; 题目大意&#xff1a; 给定一张 n 个点 m 条边的无向带权连通图&#xff0c;求一条从点 1 到点 n 的路径&#xff0c;使得经过的边权异或和最大。 路径可以经过重复点和重复边&#xff0c;当一条边被重复经过时也会相应地被 xor 多次。 s…

.NET Core 3.0 可回收程序集加载上下文

.NET诞生以来&#xff0c;程序集的动态加载和卸载都是一个Hack的技术&#xff0c;之前的NetFx都是使用AppDomain的方式去加载程序集&#xff0c;然而AppDomain并没有提供直接卸载一个程序集的API&#xff0c;而是要卸载整个AppDomain才能卸载包含在其中的所有程序集。然而卸载整…

ADPC2-G 希望

希望 题意&#xff1a; 有A&#xff0c;B两棵树&#xff0c;对于一个1到n的全排列a[i],让树A中的点i和树B的节点a[i]连一条边&#xff0c;希望指数&#xff1a;两棵树和新加入的边构成的图中&#xff0c;环长为m的环的个数。数组a[]可以任意交换位置&#xff0c;且任意&#…

.Net Core中依赖注入服务使用总结

一、依赖注入引入依赖注入的目的是为了解耦和。说白了就是面向接口编程&#xff0c;通过调用接口的方法&#xff0c;而不直接实例化对象去调用。这样做的好处就是如果添加了另一个种实现类&#xff0c;不需要修改之前代码&#xff0c;只需要修改注入的地方将实现类替换。上面的…