[bzoj P2726] [SDOI2012]任务安排
[bzoj P2726] [SDOI2012]任务安排
Time Limit: 10 Sec Memory Limit: 128 MB
Submit: 1204 Solved: 349
[Submit][Status][Discuss]
Description机器上有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 Output153
没有数据范围,差评!
自己从discuss里面搞来了:
[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 -(2^8)<=Ti<=2^80<=Fi<=2^8
看这数据范围。。
刚开始还没有想到???吃枣药丸
这题如果我们正推需要二维,最坏O(n^3),最好O(n^2),过不了啊。。
但是如果逆着来——(一下我把F数组写成g数据,个人习惯,不喜勿喷)
f[i]=min(f[j]+s*g[j]+(s+t[i]-t[j])*(g[i]-g[j])+(t[i]-t[j])*g[j])=min(f[j]+(s+t[i]-t[j])*g[i])
其中,g数组和t数组都是后缀和。
为了方便处理,我们把整个reverse一下,然后就是正常的从前往后推了。
显然,这东西很适合推斜率优化。
设k<j<i,更新f[i]时f[j]比f[k]优越当且仅当f[j]+(s+t[i]-t[j])*g[i]<f[k]+(s+t[i]-t[k])*g[i]
变形得,
(f[i]-f[k])/(t[j]-t[k])<g[i]
哈哈哈,这不就一sb题吗,g[i]递增啊。
然而出题人就这么毒瘤,时间t搞成还有负数和0,所以t数组就不是单调的了。
这。。。据说x坐标不单调要平衡树或cdq啊。。。完了。
1min。
2min。
3min。
……
nhours。。。
死磕了一下别的dalao的blog,终于会了。
这里运用cdq的思想主要还是在归并排序上面。
通过构造x坐标有序的凸包来更新解。
显然,用分治来做,处理[l..r]时先把[l..mid]搞成x坐标有序的(当然要先把这段区间的答案计算出来,即先cdq(l,mid)),
然后可以构造出一个凸包,供[mid+1..r]这段区间使用。
更新好以后[mid+1..r],并不意味着[mid+1..r]的答案确定了,因为这本段区间里点还没有被本段区间的点更新过。
所以还要调用cdq(mid+1,r)。
然后最后把区间按照t从小到大排好序。
当然,在熟练之后,很容易能推出要维护一个斜率单调递增的队列(也就是下凸壳)。
续了我。。。
据说还有一种方法,能使x坐标单调,斜率不单调?留坑。
upd:12/4 19:24
明白了怎么用二分处理。当然用二分是在斜率不单调的时候用的。
那我们就要改一下这个方程:
这里(其实上面也有)运用到了“提前计算代价”的思想。
就是说,在不影响dp的无后效性的情况下,转移当前状态时,将当前影响到后面的费用计算出来。
方程:f[i]=min{f[j]+s*(g[n]-g[j])+t[i]*(g[i]-g[j])}
其中g和t都是前缀和。这个方程转自konjac大佬的博客。
然后设k<j<i,f[j]<f[k],
则(f[j]-f[k])/(g[j]-g[k])<s+t[i]。
而g是递增的,s+t[i]则不是。
这时我们不需要cdq了,但需要二分。
怎么二分?
我们发现维护的还是一个斜率单调递增的凸包,但是查询的时候,可不能和原来那样,秉承一个单调的原则取了。
因为原来如果s+t[i]是递增的,那么你删掉了一个点q[c],那么表示slope(q[c],q[c+1])<s+t[i],那对于更大的s+t[i],这个点就没有用了,直接pop掉就好了。
但是现在情况不同,不能pop。那么,我们可以查找一个ret点,使ret是满足slope(q[ret],q[ret+1)>=s+t[i]的点中,slope(q[ret],q[ret+1)最小的一个。
换言之,就是最靠前的那一个。那我们可以通过二分查找来实现,不过需要判断边界情况。
复杂度仍然是O(nlogn)的。
code(cdq):
#include <cstdio> #include <cstring> #include <algorithm> typedef long long LL; using namespace std; void OJ() { #ifndef ONLINE_JUDGE freopen("in.txt","r",stdin); freopen("out.txt","w",stdout); #endif } namespace fastIO { #define gec(c) getchar(c) #define puc(c) putchar(c) char ch; inline int read() { ,f=; ch=getchar(); ') { if (ch=='-') f=-f; ch=gec(); } ') { x=(x<<)+(x<<)+(ch^); ch=getchar(); } return x*f; } ]; template <class T> inline void write(T x) { ) { puc('); return; } ) x=-x,puc('-'); ; x; x/=) nnn[++ttt]=x%; ); } } using namespace fastIO; ; int n,L,R; LL s; struct point { LL x,y; point () {} point (LL i,LL j) : x(i),y(j) {} } q[N]; struct mis { int i; LL t,g,v,f; } a[N],o[N]; inline double slope (point u,point v) { ?1e10:-1e10; return 1.0*(v.y-u.y)/(v.x-u.x); } inline void insert (point u) { for ( ; L<R; ) { ],q[R])>slope(q[R],u)) { --R; } else break; } q[++R]=u; } inline LL reply (LL k) { for ( ; L<R; ) { ])<1.0*k) { ++L; } else break; } return q[L].y-k*q[L].x; } #define M ((l)+(r)>>1) inline void cdq (int l,int r) { if (l>=r) return; cdq(l,M); L=,R=; for (int i=l; i<=M; ++i) { insert(point(a[i].t,a[i].f)); } ; i<=r; ++i) { a[i].f=min(a[i].f,reply(a[i].g)+a[i].v); } cdq(M+,r); ; for (int i=l; i<=r; ++i) { if (v>r||(a[u].t<a[v].t&&u<=M)) o[i]=a[u++]; else o[i]=a[v++]; } for (int i=l; i<=r; ++i) a[i]=o[i]; } inline bool cmp (const mis &u,const mis &v) { return u.i<v.i; } int main() { OJ(); n=read(),s=read(); ; i<=n; ++i) { a[i].t=read(),a[i].g=read(); a[i].i=n-i+; } for (int i=n; i; --i) { a[i].t+=a[i+].t,a[i].g+=a[i+].g; a[i].f=a[i].v=(s+a[i].t)*a[i].g; } reverse(a+,a++n); cdq(,n); sort(a+,a++n,cmp); write(a[n].f); ; }code(二分):
#include <cstdio> #include <cstring> #include <algorithm> typedef long long LL; using namespace std; void OJ() { #ifndef ONLINE_JUDGE freopen("in.txt","r",stdin); freopen("out.txt","w",stdout); #endif } namespace fastIO { #define gec(c) getchar(c) #define puc(c) putchar(c) char ch; inline int read() { ,f=; ch=getchar(); ') { if (ch=='-') f=-f; ch=gec(); } ') { x=(x<<)+(x<<)+(ch^); ch=gec(); } return x*f; } ]; template <class T> inline void write(T x) { ) { puc('); return; } ) x=-x,puc('-'); ; x; x/=) nnn[++ttt]=x%; ); } } using namespace fastIO; ; const LL inf=1e12; int n,L,R; LL s; struct point { LL x,y; point () {} point (LL i,LL j) : x(i),y(j) {} } q[N],opt; struct mis { LL t,g,f; } a[N]; inline double slope (point u,point v) { if (v.x==u.x) return v.y>u.y?inf:-inf; return 1.0*(v.y-u.y)/(v.x-u.x); } inline void insert (point u) { for ( ; L<R; ) { ],q[R])>=slope(q[R],u)) { --R; } else break; } q[++R]=u; } inline point reply (LL k) { if (L==R) return q[L]; else ],q[R])<k) return q[R]; else ])>=k) return q[L]; ,mid,ret; while (l<=r) { mid=(l+r)>>; ])>=k) { ret=mid,r=mid-; } ; } return q[ret]; } int main() { OJ(); n=read(),s=read(),a[].t=a[].g=a[].f=; ; i<=n; ++i) a[i].t=read(),a[i].g=read(); ; i<=n; ++i) a[i].t+=a[i-].t; ; i<=n; ++i) a[i].g+=a[i-].g; L=,R=,q[]=point(,); ; i<=n; ++i) { LL k=s+a[i].t; opt=reply(k); a[i].f=opt.y-k*opt.x+s*a[n].g+a[i].t*a[i].g; insert(point(a[i].g,a[i].f)); } write(a[n].f); ; }
[bzoj P2726] [SDOI2012]任务安排的更多相关文章
- BZOJ 2726: [SDOI2012]任务安排( dp + cdq分治 )
考虑每批任务对后面任务都有贡献, dp(i) = min( dp(j) + F(i) * (T(i) - T(j) + S) ) (i < j <= N) F, T均为后缀和. 与j有关 ...
- BZOJ 2726: [SDOI2012]任务安排 [斜率优化DP 二分 提前计算代价]
2726: [SDOI2012]任务安排 Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 868 Solved: 236[Submit][Status ...
- 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])) \] 然后移项 ...
- bzoj 2726: [SDOI2012]任务安排
Description 机 器上有N个需要处理的任务,它们构成了一个序列.这些任务被标号为1到N,因此序列的排列为1,2,3...N.这N个任务被分成若干批,每批包含相邻的 若干任务.从时刻0开始,这 ...
- BZOJ.2726.[SDOI2012]任务安排(DP 斜率优化)
题目链接 数据范围在这:https://lydsy.com/JudgeOnline/wttl/thread.php?tid=613, 另外是\(n\leq3\times10^5\). 用\(t_i\) ...
- 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 [SDOI2012]任务安排(斜率DP+CDQ分治)
[题目链接] http://www.lydsy.com/JudgeOnline/problem.php?id=2726 [题意] 将n个任务划分成若干个块,每一组Mi任务花费代价(T+sigma{ t ...
- BZOJ 2726: [SDOI2012]任务安排 斜率优化 + 凸壳二分 + 卡精
Code: #include<bits/stdc++.h> #define setIO(s) freopen(s".in","r",stdin) # ...
- 【BZOJ2726】[SDOI2012]任务安排 斜率优化+cdq分治
[BZOJ2726][SDOI2012]任务安排 Description 机器上有N个需要处理的任务,它们构成了一个序列.这些任务被标号为1到N,因此序列的排列为1,2,3...N.这N个任务被分成若 ...
随机推荐
- Spring restful
1. RESTful 不是一项技术,也不是一个标准,而是一种风格,跟servlet不在一个层面上,根本无法比较.一个基于servlet的application也是可以是符合RESTful风格的,换言之 ...
- CCF CSP 201703-1 分蛋糕
题目链接:http://118.190.20.162/view.page?gpid=T57 问题描述 试题编号: 201703-1 试题名称: 分蛋糕 时间限制: 1.0s 内存限制: 256.0 ...
- java0425 wen IO
- asp.net core 使用 web deploy 部署网站
1.添加角色和功能中 web服务器(iis)->管理工具->管理服务 打勾并安装 2.安装 web deploy,也可以通过 web平台安装程序 来安装,搜索web deploy就可以了 ...
- 2018年-2019年第二学期第五周C#学习个人总结
在本周我学习了第五章面向对象高级中的5.3多态,5.3多态中主要包括重写父类方法,多态的实现,base关键字,里氏转换原则,Object类.在重写父类方法中要求当重写父类的方法时,要求子类的方法名,参 ...
- 软考自查:UML建模
UML建模 内容提要 用例图 类图与对象图 顺序图 活动图 状态图 通信图 构件图 用例图 包含关系 扩展关系 泛化关系 类图与对象图 填类名,方法名,属性名 填多重度 填关系 1: ...
- 打包加载 AssetBundle
1.先创建Asset序列化(单个文件夹所在文件夹路径,会遍历这个文件夹所有的Prefab,所有的Prefab名字不能重复,必须保证名字得唯一性),配置好ConfigAB表 /* ######### # ...
- LintCode 846.多关键字排序
LintCode 846.多关键字排序 描述 给定 n 个学生的学号(从 1 到 n 编号)以及他们的考试成绩,表示为(学号,考试成绩),请将这些学生按考试成绩降序排序,若考试成绩相同,则按学号升序排 ...
- 论文阅读:Siam-RPN
摘要 Siam-RPN提出了一种基于RPN的孪生网络结构.由孪生子网络和RPN网络组成,它抛弃了传统的多尺度测试和在线跟踪,从而使得跟踪速度非常快.在VOT实时跟踪挑战上达到了最好的效果,速度最高16 ...
- Linux常用命令——软件包管理
Linux常用命令--软件包管理 Linux 模块依赖查询网址http://www.rpmfind.net/ ISO挂载 将所需ISO文件添加到虚拟机 建立挂载文件夹mkdir /mnt/cdrom ...