描述

这道题目说的是,给出了n项必须按照顺序完成的任务,每项任务有它需要占用机器的时间和价值。现在我们有一台机器可以使用,它每次可以完成一批任务,完成这批任务所需的时间为一个启动机器的时间S加上所有任务需要的时间。并且它是在完成所有任务后才会把任务的成果输出,这样我们就在那一时间时得到所有这些任务的一个完成时间。我们现在要求一种完成任务的方式使得所有任务的完成时间乘上该任务的价值之和最小。

输入

第一行,一个数n表示任务的总数

第二行,一个数s表示开机的时间

接下来n行,每行两个数a,b,a表示该任务完成所要的时间,b表示该任务的价值。

输出

输出文件包括一行,这一行只包含一个整数,就是最少价值和。

样例输入

5

1

1 3

3 2

4 3

2 3

1 4

样例输出

153

提示

【样例说明】

分组情况:

{1,2},{3},{4,5}

T=(s+1+3)(3+2)+(s+s+1+3+4)3+(s+s+s+1+3+4+2+1)*(3+4)=153

【数据规模】

对于全部的数据,保证有n<=10000。

标签

算法竞赛进阶指南


斜率优化dp入门题。

这道题需要简单的推一推式子。

我们用两个前缀和w[i],time[i]" role="presentation" style="position: relative;">w[i],time[i]w[i],time[i]分别表示价值与时间的前缀和。

用f[i]" role="presentation" style="position: relative;">f[i]f[i]表示前i个物品最优的安排需要的花费。

则有:

f[i]=min(f[j]+S∗(w[n]−w[j])+time[i]∗(w[i]−w[j]))" role="presentation" style="position: relative;">f[i]=min(f[j]+S∗(w[n]−w[j])+time[i]∗(w[i]−w[j]))f[i]=min(f[j]+S∗(w[n]−w[j])+time[i]∗(w[i]−w[j]))

其中我们使用了一种叫做费用提前计算的思想,把当前的启动时间对之后所有任务的影响都计算了出来。

但只推出这个式子每次转移是O(n)" role="presentation" style="position: relative;">O(n)O(n)的,无法匹配这道题的数据范围。

于是我们将min去掉,变成:

=>f[i]=f[j]+S∗(w[n]−w[j])+time[i]∗(w[i]−w[j])" role="presentation" style="position: relative;">f[i]=f[j]+S∗(w[n]−w[j])+time[i]∗(w[i]−w[j])f[i]=f[j]+S∗(w[n]−w[j])+time[i]∗(w[i]−w[j])

然后移个项:

=>f[j]=f[i]−S∗(w[n]−w[j])−time[i]∗(w[i]−w[j])" role="presentation" style="position: relative;">f[j]=f[i]−S∗(w[n]−w[j])−time[i]∗(w[i]−w[j])f[j]=f[i]−S∗(w[n]−w[j])−time[i]∗(w[i]−w[j])

然后展开括号并整理式子:

=>f[j]=(S+time[i])∗w[j]+f[i]−S∗w[n]−time[i]∗w[i]" role="presentation" style="position: relative;">f[j]=(S+time[i])∗w[j]+f[i]−S∗w[n]−time[i]∗w[i]f[j]=(S+time[i])∗w[j]+f[i]−S∗w[n]−time[i]∗w[i]

发现这是一个关于w[j]的一次函数,于是对于每一个j" role="presentation" style="position: relative;">jj我们对应成平面上的点(w[j],f[j])" role="presentation" style="position: relative;">(w[j],f[j])(w[j],f[j]),可以看到w[j]是单调递增的。

对于上面的式子,我们想要f[i]最小,就需要让这个一次函数的截距最小。

显然需要维护一个下凸壳,并且将过于平缓的线段(斜率小于S+time[j]" role="presentation" style="position: relative;">S+time[j]S+time[j]的一定不如后面的线段优)删去就行了。


代码:

#include<bits/stdc++.h>
#define ll long long
#define N 10005
using namespace std;
inline ll read(){
    ll ans=0;
    char ch=getchar();
    while(!isdigit(ch))ch=getchar();
    while(isdigit(ch))ans=(ans<<3)+(ans<<1)+(ch^48),ch=getchar();
    return ans;
}
int n,S,q[N],hd,tl;
ll w[N],tim[N],f[N];
inline double slope(int x,int y){return (f[x]-f[y])/(w[x]-w[y]);}
int main(){
    n=read(),S=read(),hd=1,tl=1;
    for(int i=1;i<=n;++i)tim[i]=read()+tim[i-1],w[i]=read()+w[i-1];
    for(int i=1;i<=n;++i){
        while(hd<tl&&1.0*(S+tim[i])>slope(q[hd+1],q[hd]))++hd;
        f[i]=f[q[hd]]+S*(w[n]-w[q[hd]])+tim[i]*(w[i]-w[q[hd]]);
        while(hd<tl&&slope(q[tl],q[tl-1])>slope(i,q[tl]))--tl;
        q[++tl]=i;
    }
    cout<<f[n];
    return 0;
}

2018.09.05 任务安排(斜率优化dp)的更多相关文章

  1. bzoj 2726 任务安排 斜率优化DP

    这个题目中 斜率优化DP相当于存在一个 y = kx + z 然后给定 n 个对点 (x,y)  然后给你一个k, 要求你维护出这个z最小是多少. 那么对于给定的点来说 我们可以维护出一个下凸壳,因为 ...

  2. [SDOI2012]任务安排 - 斜率优化dp

    虽然以前学过斜率优化dp但是忘得和没学过一样了.就当是重新学了. 题意很简单(反人类),利用费用提前的思想,考虑这一次决策对当前以及对未来的贡献,设 \(f_i\) 为做完前 \(i\) 个任务的贡献 ...

  3. BZOJ 2726: [SDOI2012]任务安排 [斜率优化DP 二分 提前计算代价]

    2726: [SDOI2012]任务安排 Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 868  Solved: 236[Submit][Status ...

  4. 2018.09.06 警卫安排(树形dp)

    描述 太平王世子事件后,陆小凤成了皇上特聘的御前一品侍卫. 皇宫以午门为起点,直到后宫嫔妃们的寝宫,呈一棵树的形状:有边直接相连的宫殿可以互相望见.大内保卫森严,三步一岗,五步一哨,每个宫殿都要有人全 ...

  5. BZOJ 2726 [SDOI2012] 任务安排 - 斜率优化dp

    题解 转移方程与我的上一篇题解一样 : $S\times sumC_j  + F_j = sumT_i \times sumC_j + F_i - S \times sumC_N$. 分离成:$S\t ...

  6. 2018.09.05 bzoj1010: [HNOI2008]玩具装箱toy(斜率优化dp)

    传送门 一道经典的斜率优化dp. 推式子ing... 令f[i]表示装前i个玩具的最优代价. 然后用老套路. 我们只考虑把第j+1" role="presentation" ...

  7. 2018.09.29 bzoj3675: [Apio2014]序列分割(斜率优化dp)

    传送门 斜率优化dp经典题目. 首先需要证明只要选择的K个断点是相同的,那么得到的答案也是相同的. 根据分治的思想,我们只需要证明有两个断点时成立,就能推出K个断点时成立. 我们设两个断点分成的三段连 ...

  8. 2018.09.10 bzoj1597: [Usaco2008 Mar]土地购买(斜率优化dp)

    传送门 终究还是通宵了啊... 这是一道简单的斜率优化dp. 先对所有土地排序,显然如果有严格小于的两块土地不用考虑小的一块. 于是剩下的土地有一条边单增,另外一条单减. 我们假设a[i]是单减的,b ...

  9. 2018.09.07 bzoj1096: [ZJOI2007]仓库建设(斜率优化dp)

    传送门 斜率优化dp经典题. 令f[i]表示i这个地方修建仓库的最优值,那么答案就是f[n]. 用dis[i]表示i到1的距离,sump[i]表示1~i所有工厂的p之和,sum[i]表示1~i所有工厂 ...

随机推荐

  1. 微信公众号开发者模式自定义菜单 node

    纯属分享 var config = require('./admin/wx/config/config'); var API = require('wechat-api'); var api = ne ...

  2. myeclipse中解决 java heap space/gc overhead limit exceeded eclipse 的方法

    在Eclipse打包的时候报错:gc overhead limit exceeded eclipse 原因是Eclipse默认配置内存太小须要更改安装Eclipse目录下的eclipse.ini文件. ...

  3. UI5-文档-4.32-Routing with Parameters

    现在我们可以在overview和detail页面之间导航,但是我们在overview中选择的实际项目还没有显示在detail页面上.我们的应用程序的一个典型用例是在详细信息页面上显示所选项目的附加信息 ...

  4. import 语句用于导入从外部模块,另一个脚本等导出的函数,对象或原语。

    import 语句用于导入从外部模块,另一个脚本等导出的函数,对象或原语. 注意:此功能目前无法在任何浏览器中实现.它在许多转换器中实现,例如 Traceur Compiler , Babel , R ...

  5. jstatd - Virtual Machine jstat Daemon

    jstatd [options] 参数:options 命令行参数,可以按任何顺序,但如果有多余的或者中有互斥的参数,最后制定的那个参数将有优先权 options: -nr 当一个存在的RMI Reg ...

  6. 迷你MVVM框架 avalonjs 学习教程20、路由系统

    SPA的成功离开不这三个东西,分层架构,路由系统,储存系统.分层架构是我们组织复杂代码的关键,这里特指MVVM的avalon:路由系统是将多个页面压缩在一个页面的关键:储存系统特指本地储存,是安全保存 ...

  7. Hibernate 的update语句性能详解

    Hibernate 中如果直接使用 Session.update(Object o); 会把这个表中的所有字段更新一遍. 比如: view plaincopy to clipboardprint? p ...

  8. SQL语句查询年龄分段分组查询

    此情况用于数据库中没有“年龄”这个字段,只有“出生日期”这个字段.先计算出“年龄”,在分组查询. 1.SELECT *, ROUND(DATEDIFF(CURDATE(), popBirthday)/ ...

  9. 序列比对之Biostrings包

    基本概念 Biostrings包很重要的3个功能是进行Pairwise sequence alignment 和Multiple sequence alignment及 Pattern finding ...

  10. 基于Woodstox的StAX 2 (Streaming API for XML)解析XML

    StAX (Streaming API for XML)面向流的拉式解析XML,速度快.占用资源少,非常合适处理大数据量的xml文件. 详细教程和说明可以参见以下几篇文章: 使用 StAX 解析 XM ...