BZOJ2726 [SDOI2012]任务安排 【斜率优化 + cdq分治】
题目
机器上有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分治】的更多相关文章
- 【BZOJ2726】[SDOI2012]任务安排 斜率优化+cdq分治
[BZOJ2726][SDOI2012]任务安排 Description 机器上有N个需要处理的任务,它们构成了一个序列.这些任务被标号为1到N,因此序列的排列为1,2,3...N.这N个任务被分成若 ...
- [bzoj2726][SDOI2012]任务安排 ——斜率优化,动态规划,二分,代价提前计算
题解 本题的状态很容易设计: f[i] 为到第i个物件的最小代价. 但是方程不容易设计,因为有"后效性" 有两种方法解决: 1)倒过来设计动态规划,典型的,可以设计这样的方程: d ...
- BZOJ_3963_[WF2011]MachineWorks_斜率优化+CDQ分治
BZOJ_3963_[WF2011]MachineWorks_斜率优化+CDQ分治 Description 你是任意性复杂机器公司(Arbitrarily Complex Machines, ACM) ...
- [Noi2014]购票 BZOJ3672 点分治+斜率优化+CDQ分治
Description 今年夏天,NOI在SZ市迎来了她30周岁的生日.来自全国 n 个城市的OIer们都会从各地出发,到SZ市参加这次盛会.全国的城市构成了一棵以SZ市为根的有根树,每个城市与它的 ...
- 【BZOJ-1492】货币兑换Cash DP + 斜率优化 + CDQ分治
1492: [NOI2007]货币兑换Cash Time Limit: 5 Sec Memory Limit: 64 MBSubmit: 3396 Solved: 1434[Submit][Sta ...
- 洛谷.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_ ...
- BZOJ3963 WF2011MachineWorks(动态规划+斜率优化+cdq分治)
按卖出时间排序后,设f[i]为买下第i台机器后的当前最大收益,则显然有f[i]=max{f[j]+gj*(di-dj-1)+rj-pi},且若此值<0,应设为-inf以表示无法购买第i台机器. ...
- bzoj1492/luogu4027 货币兑换 (斜率优化+cdq分治)
设f[i]是第i天能获得的最大钱数,那么 f[i]=max{在第j天用f[j]的钱买,然后在第i天卖得到的钱,f[i-1]} 然后解一解方程什么的,设$x[j]=\frac{F[j]}{A[j]*Ra ...
- BZOJ 2726: [SDOI2012]任务安排 [斜率优化DP 二分 提前计算代价]
2726: [SDOI2012]任务安排 Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 868 Solved: 236[Submit][Status ...
随机推荐
- moment算本月开始日期和结束日期
moment算本月开始日期和结束日期 1.引入moment.js var vStartDate=new moment().add('month',addMonth).format("YYYY ...
- HTML5文档结构 摘要
<!DOCType html>--声明文档结构类型 <html lang=zh-cn> <head> <meta charset=utf-8> < ...
- 快速WCF
初级原理:通得过地址调用接口服务,接口服务调用对应实现方法 援引文章地址:http://www.cnblogs.com/iamlilinfeng/archive/2012/09/25/2700049. ...
- crontab 应用
可以用crontab -e 添加要执行的命令. 命令执行的结果,无论是标准输出还是错误输出,都将以邮件形式发给用户. 添加的命令必须以如下格式: * * * * * /co ...
- The - Modcrab——使用贪心策略
一.题目信息 The - Modcrab 简单翻译一下:Vova有生命值h1,每次攻击值为a1,每瓶药水恢复生命值c1;Modcrab有生命值h2,每次攻击值为a2.在每个关卡开始,Vova有两种选择 ...
- noj-1102-黑白图像
1 //题目地址:http://acm.njupt.edu.cn/acmhome/problemdetail.do?method=showdetail&id=1102 ...
- Ubuntu12.04安装Chrome浏览器,并添加到左侧的启动栏
在google官网下载google chrome deb包,有32位和64位之分: 怎么判断系统是32位还是64位的,可以用以下代码: ; int *p = &a; printf(" ...
- Hanoi双塔问题
题目描述: 给定A.B.C三根足够长的细柱,在A柱上放有2n个中间有孔的圆盘,共有n个不同的尺寸,每个尺寸都有两个相同的圆盘,注意这两个圆盘是不加区分的(下图为n=3的情形).现要将这些圆盘移到C柱上 ...
- Bzoj 1055: [HAOI2008]玩具取名 (区间DP)
Bzoj 1055: [HAOI2008]玩具取名 (区间DP) 题目链接:https://www.lydsy.com/JudgeOnline/problem.php?id=1055 区间动态规划和可 ...
- 【图论】hdu6370Werewolf
有理有据的结论题 Problem Description "The Werewolves" is a popular card game among young people.In ...