BZOJ2726【SDOI2012】任务安排(斜率优化Dp+二分查找)
由题目条件显然可以得到状态 f[i][j] 表示以 i 为结尾且 i 后作为断点,共做了 j 次分组的最小代价。
因此转移变得很显然:f[i][j]=min{f[k][j-1]+(s×j+sumT[i])×(sumC[i]-sumC[k])} (0≤k<i)
sumT[i]表示时间的前缀和,sumC[i]表示代价的前缀和
但是绝望的是显然时间复杂度是O(n³),2D/1D的动态规划显然无法解决一题(但是如果能使用斜率优化也可以优化为O(n²)的程度,但显然毫无卵用QAQ)
所以我们来优化状态,无法避免对 i 的枚举,所以优化 j 成了必然,由于在转移中出现了s×j这恐怖的一项,导致不得不去枚举 j 的数值,但是我们将s×j提出,不难发现对于每组机器的开机时间 s 对最终答案造成的影响是 s×(sumC[n]-sum[k]),所以我们对当前的状态提前加上这个值,就可以很巧妙的避免了对 j 的枚举。
所以新的状态油然而生 f[i] 表示前 i 个任务当前断点在 i 后的最小代价。
转移也很是自然:f[i]=min{f[j]+(s+sumT[i])×(sumC[i]-sumC[j])}+s×(sumC[n]-sumC[i])
此时这个1D/1D的动态规划在此时已经在状态的维度上达到了最优,所以一堆大佬已经开始了斜率优化切题过程,但是作为蒟蒻的我们还是先来研究一下斜率优化的本质QWQ。
……
不妨先来降低一波难度吧假设对于所有时间 T 都是正的,我们该如何解决这道题呢?
显然这无数转移之中我们早可以隐约发现其中有无数不必要的枚举,所以我们可以假设 j1<j2<i 时,对于当前的 i 来说 j2 比 j1 更优,不难得到一下的式子:
f[j1]+(s+sumT[i])×(sumC[i]-sumC[j1])≥f[j2]+(s+sumT[i])×(sumC[i]-sumC[j2])
由于有关 i 的变量在此时对于当前状态来说相当于常量,所以我们应该将与 i 有关的式子移到一边,可得:
f[j2]-f[j1]-s×(sumC[j2]-sumC[j1])≤sumT[i]×(sumC[j2]-sumC[j1])
同除以(sumC[j2]-sumC[j1])得:
f[j2]-f[j1]-s×(sumC[j2]-sumC[j1])/(sumC[j2]-sumC[j1])≤sumT[i]
所以当满足以上的关系式的时候,对于状态 i 来说 j1 已经无用,j2 仍是有用的。
所以我们不妨设G(j1,j2)=f[j2]-f[j1]-s×(sumC[j2]-sumC[j1])/(sumC[j2]-sumC[j1]),
若出现 j1,j2,j3 时,当G(j1,j2)≥G(j2,j3)这种情况发生时,无论sumT[i]取何值,j2都不可能为最优。(这一步的讨论十分关键)
由此我们需要维护一个严格单调递增的队列即可对于当前的状态 i O(1)求出它的最有转移,这就是我们俗称的斜率优化。

如果在坐标系中分析,则更为清晰对于虚线而言,实线连接的三个点中中间的点永远不可能成为最用,随即这便是斜率优化名称的由来,因为它像极了斜率的式子,我们只需要维护一个凹壳就可以了!!!QWQ
……
分析完水题我们再来看一看原题吧,如果 T 又负数,相当于 sumT[i] 不是单调的,我们仍需要维护凹壳,因为它满足我们上方证明的最优性,所以我们在查找上需要花点心思,仔细一想这也非常简单,只需要二分出适合于当前斜率 sumT[i] 的区间,也就是寻找 G(j2,j3)>=sumT[i] 且 G(j1,j2)<=sumT[i],则此时 j2 为当前的最有转移QAQ,代码实现也没有什么难度嘻嘻!!!
所以善良的我会告诉你们代码如下:
#include<cstdio>
#include<algorithm>
#define rep(i,l,r) for (int i=l; i<=r; i++)
typedef long long ll;
using namespace std; const int N=;
ll T[N],F[N],f[N];
int n,s,S,st,ed,q[N]; ll Y(int j){ return f[j]-F[n]*T[j]+F[j]*T[j]-F[j]*S; } void dp(){
st=ed=;
rep(i,,n){
int l=,r=ed-,ans=ed;
while (l<=r){
ll mid=(l+r)>>;
if (1ll*(F[q[mid+]]-F[q[mid]])*T[i]<=Y(q[mid+])-Y(q[mid])) ans=mid,r=mid-; else l=mid+;
}
int j=q[ans]; f[i]=f[j]+(F[n]-F[j])*(T[i]-T[j]+S);
while (st<ed && 1ll*(Y(q[ed])-Y(q[ed-]))*(F[i]-F[q[ed]])>=(Y(i)-Y(q[ed]))*(F[q[ed]]-F[q[ed-]])) ed--;
q[++ed]=i;
}
} int main(){
scanf("%d%d",&n,&S);
rep(i,,n) scanf("%lld%lld",&T[i],&F[i]),T[i]+=T[i-],F[i]+=F[i-];
dp(); printf("%lld\n",f[n]);
return ;
}
emmmm,代码我是网上拷贝的主要是时间太晚了,大家见谅QAQ,第一遍博客希望很多人关注,加油加油!!!

BZOJ2726【SDOI2012】任务安排(斜率优化Dp+二分查找)的更多相关文章
- BZOJ 2726: [SDOI2012]任务安排 [斜率优化DP 二分 提前计算代价]
2726: [SDOI2012]任务安排 Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 868 Solved: 236[Submit][Status ...
- [SDOI2012]任务安排 - 斜率优化dp
虽然以前学过斜率优化dp但是忘得和没学过一样了.就当是重新学了. 题意很简单(反人类),利用费用提前的思想,考虑这一次决策对当前以及对未来的贡献,设 \(f_i\) 为做完前 \(i\) 个任务的贡献 ...
- [bzoj2726][SDOI2012]任务安排 ——斜率优化,动态规划,二分,代价提前计算
题解 本题的状态很容易设计: f[i] 为到第i个物件的最小代价. 但是方程不容易设计,因为有"后效性" 有两种方法解决: 1)倒过来设计动态规划,典型的,可以设计这样的方程: d ...
- BZOJ 2726 [SDOI2012] 任务安排 - 斜率优化dp
题解 转移方程与我的上一篇题解一样 : $S\times sumC_j + F_j = sumT_i \times sumC_j + F_i - S \times sumC_N$. 分离成:$S\t ...
- bzoj 2726 任务安排 斜率优化DP
这个题目中 斜率优化DP相当于存在一个 y = kx + z 然后给定 n 个对点 (x,y) 然后给你一个k, 要求你维护出这个z最小是多少. 那么对于给定的点来说 我们可以维护出一个下凸壳,因为 ...
- 【BZOJ2726】[SDOI2012]任务安排 斜率优化+cdq分治
[BZOJ2726][SDOI2012]任务安排 Description 机器上有N个需要处理的任务,它们构成了一个序列.这些任务被标号为1到N,因此序列的排列为1,2,3...N.这N个任务被分成若 ...
- [小A与最大子段和][斜率优化dp+二分]
链接:https://ac.nowcoder.com/acm/contest/545/A来源:牛客网题目描述 小A在网上看到了 "最大子段和" 问题的解法.第二天,小A向小B讲解了 ...
- 2018.09.05 bzoj2726: [SDOI2012]任务安排(斜率优化dp+二分)
传送门 跟Ti" role="presentation" style="position: relative;">TiTi为正数的时候差不多. ...
- BZOJ 2726: [SDOI2012]任务安排 斜率优化 + 凸壳二分 + 卡精
Code: #include<bits/stdc++.h> #define setIO(s) freopen(s".in","r",stdin) # ...
随机推荐
- SpringMVC中Freemarker获取项目根目录
https://blog.csdn.net/whatlookingfor/article/details/51538995 在SpringMVC框架中使用Freemarker试图时,要获取根路径的方式 ...
- UWP 后台保存图片
在做UWP的时候,有一个需求,就是点击下载按钮,需要将当前页面中的Image控件中显示的图片保存下来. 既然聊到了下载图片,索性把添加图片也讲一下. 一:给Image控件添加图片 xaml代码: &l ...
- Linux、Windows 下分割、合并rar文件
1.分割rar 1.1 linux下分割压缩rar 安装rar和unrar和序 $sudo aptitude install rar unrar 示例,分割压缩temp文件,每个包为1MB $rar ...
- 494 Target Sum 目标和
给定一个非负整数数组,a1, a2, ..., an, 和一个目标数,S.现在你有两个符号 + 和 -.对于数组中的任意一个整数,你都可以从 + 或 -中选择一个符号添加在前面.返回可以使最终数组和为 ...
- [转]VC++中对文件的写入和读取
本文转自:http://blog.csdn.net/fanghb_1984/article/details/7425705 本文介绍两种方法对文件进行读取和写入操作:1.采用fstream类:2.采用 ...
- mac上的应用提权
一个mac上的app需要在/Applications/My.app/Contents/MacOS路径下创建一个配置文件,在开启root权限的账户下运行时ok,但是在没有开启root权限的账户下运行时, ...
- SQL Server 2012使用OFFSET/FETCH NEXT分页及性能测试
最近在网上看到不少文章介绍使用SQL Server 2012的新特性:OFFSET/FETCH NEXT 实现分页.多数文章都是引用或者翻译的这一篇<SQL Server 2012 - Serv ...
- File.Exists 文件不存在 Or FileNotFoundException
标题警告,本文仅限走投无路,最终可能的一个问题导致. 最开始出现在找不到文件,测试发现: 看起来毫无毛病 而后各种测试: 注意看,第一行跟第三行一模一样 发现[@"]这两个字符有毒,如 ...
- Oracle ORA
ORA-00001: 违反唯一约束条件 (.) 错误说明:当在唯一索引所对应的列上键入重复值时,会触发此异常. ORA-00017: 请求会话以设置跟踪事件 ORA-00018: 超出最大会话数 OR ...
- Vue.js系列之vue-router(上) (转载自向朔1992)
概述 Vue非常适用于实践单页面应用程序也就是平时大家说的比较多的SPA(single page application),这点应该了解过Vue的应该都知道吧.一般的单页面应用是基于路由或页面之间的链 ...