任务安排 HYSBZ - 2726 (斜率优化 + 二分)

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

Input

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

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

Output

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

Sample Input5 1
1 3
3 2
4 3
2 3
1 4

Sample Output153Hint

solution:

设F[i]表示前i个任务完成后最小的代价。

然后把后面的代价提前计算。

设sx[],sy[]分别为x,y的前缀和。

F[i]=F[j]+(m+sx[i]-sx[j])*(sy[n]-sy[j])。设sum=sy[n]。

然后斜率优化

因为插入的点的横坐标仍然是单调的所以并不需要动态维护凸壳。

维护下凸壳就行了

询问斜率不单调的话直接二分找直线和凸壳的切点即可。

CODE:

 1 #include<cstdio>
 2 #include<algorithm>
 3 #define rep(i,l,r) for (int i=l; i<=r; i++)
 4 typedef long long ll;
 5 using namespace std;
 6
 7 const int N=1000010;
 8 ll T[N],F[N],f[N];
 9 int n,s,S,st,ed,q[N];
10
11 double Y(int j){ return f[j]-F[n]*T[j]+F[j]*T[j]-F[j]*S; }
12
13 void dp(){
14     st=ed=0;
15     rep(i,1,n){
16         int l=0,r=ed-1,ans=ed;
17         while (l<=r){
18             ll mid=(l+r)>>1;
19             if ((double)(F[q[mid+1]]-F[q[mid]])*T[i]<=Y(q[mid+1])-Y(q[mid])) ans=mid,r=mid-1; else l=mid+1;
20         }
21         int j=q[ans]; f[i]=f[j]+(F[n]-F[j])*(T[i]-T[j]+S);
22         while (st<ed && (Y(q[ed])-Y(q[ed-1]))*(F[i]-F[q[ed]])>=(Y(i)-Y(q[ed]))*(F[q[ed]]-F[q[ed-1]])) ed--;
23         q[++ed]=i;
24     }
25 }
26
27 int main(){
28
29     scanf("%d%d",&n,&S);
30     rep(i,1,n) scanf("%lld%lld",&T[i],&F[i]),T[i]+=T[i-1],F[i]+=F[i-1];
31     dp(); printf("%lld\n",f[n]);
32     return 0;
33 }

原文地址:https://www.cnblogs.com/zhangbuang/p/11134609.html

时间: 2024-10-11 08:23:39

任务安排 HYSBZ - 2726 (斜率优化 + 二分)的相关文章

洛谷P2365 任务安排 [解法二 斜率优化]

解法一:http://www.cnblogs.com/SilverNebula/p/5926253.html 解法二:斜率优化 在解法一中有这样的方程:dp[i]=min(dp[i],dp[j]+(sumf[i]-sumf[j])*sumt[i]+s*(sumf[n]-sumf[j]) ) 其中min的后半部分,也就是dp[j]+(sumf[i]-sumf[j])*sumt[i]+s*(sumf[n]-sumf[j]) 计算了将j~i分为一组的花费(以及提前计算的受影响花费) 设f(j)=dp[

bzoj 2726: [SDOI2012]任务安排【cdq+斜率优化】

cdq复健.jpg 首先列个n方递推,设sf是f的前缀和,st是t的前缀和: \[ f[i]=min(f[j]+s*(sf[n]-sf[j])+st[i]*(sf[i]-sf[j])) \] 然后移项: \[ f[i]=f[j]+s*sf[n]-s*sf[j]+st[i]*sf[i]-st[i]*sf[j] \] \[ f[i]=f[j]+s*sf[n]+st[i]*sf[i]-s*sf[j]-st[i]*sf[j] \] \[ f[i]=f[j]+s*sf[n]+st[i]*sf[i]-sf[

小A与最大子段和 斜率优化 + 二分 + 细节

Code: #include <bits/stdc++.h> #define setIO(s) freopen(s".in","r",stdin) #define x(i) (1.0000*i) #define y(i) (1.0000*s2[i]*i-1.00000*s1[i]) #define maxn 300000 #define ll long long #define ldb double using namespace std; int ta

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

2726: [SDOI2012]任务安排 Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 868  Solved: 236[Submit][Status][Discuss] Description 机器上有N个需要处理的任务,它们构成了一个序列.这些任务被标号为1到N,因此序列的排列为1,2,3...N.这N个任务被分成若干批,每批包含相邻的若干任务.从时刻0开始,这些任务被分批加工,第i个任务单独完成所需的时间是Ti.在每批任务开始前,机器需要启

poj 2726: [SDOI2012]任务安排【斜率优化dp】

我会斜率优化了!这篇讲的超级棒https://blog.csdn.net/shiyongyang/article/details/78299894?readlog 首先列个n方递推,设sf是f的前缀和,st是t的前缀和:\( f[i]=min(f[j]+s(sf[n]-sf[j])+st[i](sf[i]-sf[j])) \) 然后移项: \[ f[i]=f[j]+s*sf[n]-s*sf[j]+st[i]*sf[i]-st[i]*sf[j] \] \[ f[i]=f[j]+s*sf[n]+st

Codeforces Round #344 (Div. 2) E. Product Sum 二分斜率优化DP

E. Product Sum Blake is the boss of Kris, however, this doesn't spoil their friendship. They often gather at the bar to talk about intriguing problems about maximising some values. This time the problem is really special. You are given an array a of

BZOJ 2402 陶陶的难题II 二分答案+斜率优化+树链剖分+线段树维护凸包

题目大意:给定一棵树,每个点有两个坐标(x1,y1)和(x2,y2),多次询问某条链上选择两个点i和j(可以相同),求(y1i+y2j)/(x1i+x2j)的最大值 我竟没看出来这是01分数规划...真是老了... 二分答案ans,问题转化成验证(y1i+y2j)/(x1i+x2j)是否>=ans 将式子变形可得(y1i-ans*x1i)+(y2j-ans*x2j)>=0 加号两边独立,分别计算即可 问题转化为求链上y-ans*x最大的点 令P=y-ans*x 则y=ans*x+P 我们发现这

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

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

[洛谷U22158]策划体验(树上斜率优化)(二分最优决策)

题目背景 OL不在,Clao又在肝少*前线,他虽然觉得这个游戏的地图很烦,但是他认为地图的难度还是太低了,习习中作为策划还不够FM,于是他自己YY了一种新的地图和新的机制: 题目描述 整个地图呈树形结构,共有N+1 个节点,0 号节点为树的根节点,并且,与0 号节点相连的就只有1 号节点,除0 号节点外的所有节点上都会有一队战斗力为V_i的敌人存在: 指挥部设在0 号节点,玩家的操纵梯队只能出生在该节点,并且在进入地图时玩家将选择任意一个节点作为本次任务的终点,设为E ,玩家只需要将根节点到EE