题目

机器上有N个需要处理的任务,它们构成了一个序列。这些任务被标号为1到N,因此序列的排列为1,2,3...N。这N个任务被分成若干批,每批包含相邻的若干任务。从时刻0开始,这些任务被分批加工,第i个任务单独完成所需的时间是Ti。在每批任务开始前,机器需要启动时间S,而完成这批任务所需的时间是各个任务需要时间的总和。注意,同一批任务将在同一时刻完成。每个任务的费用是它的完成时刻乘以一个费用系数Fi。请确定一个分组方案,使得总费用最小。

输入格式

第一行两个整数,N,S。

接下来N行每行两个整数,Ti,Fi。

输出格式

一个整数,为所求的答案。

输入样例

5 1

1 3

3 2

4 3

2 3

1 4

输出样例

153

提示

[1, 4] 0<N<=1000 0<=S<=2^8 0<=Ti<=2^8 0<=Fi<=2^8

[5, 12] 0<N<=300000 0<=S<=2^8 0<=Ti<=2^8 0<=Fi<=2^8

[13, 20] 0<N<=100000 0<=S<=2^8 -(28)<=Ti<=28 0<=Fi<=2^8

题解

时间可以为负是什么鬼。。。

由于一个任务代价是完成时间乘以权值,所以我们可以看做没过一个时间都要花费当前所有没完成的任务的权值

设\(f[i]\)为前\(i\)个任务决策完成的最小代价,我们很容易可以得到一个dp方程

\(f[i] = max(f[j] + (F[i] - F[j]) * (T[i] - T[j] + s))\)

其中F和T都指前缀和

稍微整理一下就是一个斜率优化的式子

但是由于\(Ti\)可以为负,所以T不保证单调,不能使用单调队列

要么用splay维护凸包,要么就用cdq分治

当然是选择简短好写的cdq分治啦

#include<iostream>
#include<cstdio>
#include<cmath>
#include<cstring>
#include<algorithm>
#define LL long long int
using namespace std;
const int maxn = 300005,maxm = 100005;
const LL INF = 1000000000000000000ll;
inline int read(){
int out = 0,flag = 1; char c = getchar();
while (c < 48 || c > 57){if (c == '-') flag = -1; c = getchar();}
while (c >= 48 && c <= 57){out = (out << 3) + (out << 1) + c - 48; c = getchar();}
return out * flag;
}
struct node{
LL t,x,y,k;
}e[maxn],t[maxn];
inline bool operator <(const node& a,const node& b){
return a.x == b.x ? a.y < b.y : a.x < b.x;
}
inline bool cmp(const node& a,const node& b){
return a.k < b.k;
}
int n;
LL T[maxn],w[maxn],f[maxn],s;
int st[maxn],top;
void cdq(int l,int r){
if (l == r){
e[l].x = w[l];
e[l].y = f[l] + w[l] * T[l] - s * w[l] - w[n] * T[l];
return;
}
int mid = l + r >> 1,li = l,ri = mid + 1;
for (int i = l; i <= r; i++){
if (e[i].t <= mid) t[li++] = e[i];
else t[ri++] = e[i];
}
for (int i = l; i <= r; i++) e[i] = t[i];
cdq(l,mid);
top = 0;
for (int i = l; i <= mid; i++){
while (top > 1 && (e[i].x - e[st[top - 1]].x) * (e[st[top]].y - e[st[top - 1]].y) - (e[i].y - e[st[top - 1]].y) * (e[st[top]].x - e[st[top - 1]].x) >= 0)
top--;
st[++top] = i;
}
int j = 1;
for (int i = mid + 1; i <= r; i++){
while (j < top && e[st[j + 1]].y - e[st[j]].y <= (e[st[j + 1]].x - e[st[j]].x) * e[i].k)
j++;
f[e[i].t] = min(f[e[i].t],-e[st[j]].x * e[i].k + e[st[j]].y + w[n] * e[i].k + w[n] * s);
}
cdq(mid + 1,r);
li = l; ri = mid + 1;
for (int i = l; i <= r; i++){
if (ri > r || (li <= mid && e[li] < e[ri])) t[i] = e[li++];
else t[i] = e[ri++];
}
for (int i = l; i <= r; i++) e[i] = t[i];
}
int main(){
n = read(); s = read();
for (int i = 1; i <= n; i++){
T[i] = T[i - 1] + read();
w[i] = w[i - 1] + read();
}
for (int i = 1; i <= n; i++){
e[i].t = i;
e[i].k = T[i];
f[i] = INF;
}
sort(e + 1,e + 1 + n,cmp);
cdq(0,n);
printf("%lld\n",f[n]);
return 0;
}

BZOJ2726 [SDOI2012]任务安排 【斜率优化 + cdq分治】的更多相关文章

  1. 【BZOJ2726】[SDOI2012]任务安排 斜率优化+cdq分治

    [BZOJ2726][SDOI2012]任务安排 Description 机器上有N个需要处理的任务,它们构成了一个序列.这些任务被标号为1到N,因此序列的排列为1,2,3...N.这N个任务被分成若 ...

  2. [bzoj2726][SDOI2012]任务安排 ——斜率优化,动态规划,二分,代价提前计算

    题解 本题的状态很容易设计: f[i] 为到第i个物件的最小代价. 但是方程不容易设计,因为有"后效性" 有两种方法解决: 1)倒过来设计动态规划,典型的,可以设计这样的方程: d ...

  3. BZOJ_3963_[WF2011]MachineWorks_斜率优化+CDQ分治

    BZOJ_3963_[WF2011]MachineWorks_斜率优化+CDQ分治 Description 你是任意性复杂机器公司(Arbitrarily Complex Machines, ACM) ...

  4. [Noi2014]购票 BZOJ3672 点分治+斜率优化+CDQ分治

    Description  今年夏天,NOI在SZ市迎来了她30周岁的生日.来自全国 n 个城市的OIer们都会从各地出发,到SZ市参加这次盛会.全国的城市构成了一棵以SZ市为根的有根树,每个城市与它的 ...

  5. 【BZOJ-1492】货币兑换Cash DP + 斜率优化 + CDQ分治

    1492: [NOI2007]货币兑换Cash Time Limit: 5 Sec  Memory Limit: 64 MBSubmit: 3396  Solved: 1434[Submit][Sta ...

  6. 洛谷.4655.[CEOI2017]Building Bridges(DP 斜率优化 CDQ分治)

    LOJ 洛谷 \(f_i=s_{i-1}+h_i^2+\min\{f_j-s_j+h_j^2-2h_i2h_j\}\),显然可以斜率优化. \(f_i-s_{i-1}-h_i^2+2h_ih_j=f_ ...

  7. BZOJ3963 WF2011MachineWorks(动态规划+斜率优化+cdq分治)

    按卖出时间排序后,设f[i]为买下第i台机器后的当前最大收益,则显然有f[i]=max{f[j]+gj*(di-dj-1)+rj-pi},且若此值<0,应设为-inf以表示无法购买第i台机器. ...

  8. bzoj1492/luogu4027 货币兑换 (斜率优化+cdq分治)

    设f[i]是第i天能获得的最大钱数,那么 f[i]=max{在第j天用f[j]的钱买,然后在第i天卖得到的钱,f[i-1]} 然后解一解方程什么的,设$x[j]=\frac{F[j]}{A[j]*Ra ...

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

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

随机推荐

  1. 安装Pywin32后无法正常引用pyd文件

    1. 首先在官方下载pywin32 2.下载完成后,无法正常引用pyd文件 3.解决方案: python安装目录\Lib\site-packages\pywin32_system32\* 至 C:\W ...

  2. codevs 2915 期末考试

    时间限制: 1 s  空间限制: 16000 KB  题目等级 : 黄金 Gold 题目描述 Description 期末考试要来了,某同学正在努力复习. 他要复习N个知识点,每个知识点需要一定的知识 ...

  3. JAVA 配置

    JAVA 版本为jdk-7u25-windows-x64 Java 下载地址为: .CLASSPATH .;%JAVA_HOME%\lib\dt.jar;%JAVA_HOME%\lib\tools.j ...

  4. 如何在vue项目中使用sass(scss)

    1.用npm/cnpm/yarn安装sass的依赖包 npm install --save-dev sass-loader npm install --save-dev node-sass 或者: y ...

  5. 【转】将Eclipse中的CTRL+K搬到IDEA中

    https://my.oschina.net/sprieo/blog/224838 IDEA的该功能是CTRL+F3,行为是获取当前光标位置的单词然后调用搜索.只需要按CTRL+F3一次,就可以实现C ...

  6. 【求助】NdisSend,自定义数据包发送失败?

    做ndis hook的时候,自定义了一个数据包,包结构应该没有问题,填充NDIS_PACKET结构是这样的,先初始化:        NdisAllocatePacketPool(&nStat ...

  7. (9)zabbix创建监控项item

    1. 创建监控项 点击配置(configuration)->主机(Hosts)->在你要配置的主机一栏上点击Items->点击create item.具体看截图,各个参数我都已经标注 ...

  8. UNIX环境C语言进程控制

    一.进程ID 进程ID即是进程标识,每一个进程都会有一个唯一的非负整数来作为它的进程ID. ID为0的进程通常是调度进程,也可称为交换进程,该进程是内核的一部分,不执行硬盘上的程序,因此也被称为系统进 ...

  9. mysql:破解MySQL密码的一种方法

    1, 修改mysql配置文件/etc/my.cnf 12 [mysqld]skip_grant_tables 2, 重启mysql后直接用root用户登录(不用输入密码) 1 $ mysql -uro ...

  10. laravel服务容器(IOC控制反转,DI依赖注入),服务提供者,门脸模式

    laravel的核心思想: 服务容器: 容器:就是装东西的,laravel就是一个个的对象 放入:叫绑定 拿出:解析 使用容器的目的:这里面讲到的是IOC控制反转,主要是靠第三方来处理具体依赖关系的解 ...