[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个任务被分成若 ...
随机推荐
- python模块部分----模块、包、常用模块
0.来源:https://www.cnblogs.com/jin-xin/articles/9987155.html 1.导入模块 1.1模块就是一个python文件,模块名是文件名 1.2导入模块的 ...
- nginx运用
1.nginx的 命令 start nginx 这样,nginx 服务就启动了.打开任务管理器,查看 nginx.exe 进程,有二个进程会显示,占用系统资源,那是相当的少.然后再打开浏览器,输入 h ...
- Delphi的TService 服务路径获取 Dll中获取文件路径
研究delphi服务的路径,试了好几个方法 ,都没取出来,最后发现,要采用取DLL路径的方法 //一.获取Dll自身路径 //1)方法一: Function GetDllPath(sDllName:s ...
- css 修改input中placeholder提示问题颜色
input::-webkit-input-placeholder, textarea::-webkit-input-placeholder { color: rgba(74, 87, 103, 1); ...
- lsyncd+rsync配置图片资源双向同步
需求:为保证国内外图片加载速度,国内请求上传图片资源地址阿里云oss,国外请求上传图片资源地址aws s3,为保证图片资源的一致性,需定时进行oss和s3图片双向同步 调研方案:由于之前配置过inot ...
- SAP abap 内表增加字段方法,结构复用
1.include data: begin of gth_qamr. include structure qamr. data: kurztext like qamv-kurztext ...
- LeetCode120-Triangle-数组,动态规划
题目描述 Problem Description: Given a triangle, find the minimum path sum from top to bottom. Each ste ...
- 【我的前端自学之路】【HTML5】.html和.htm的区别
以下为自学笔记内容,仅供参考. 转发请保留原文链接:https://www.cnblogs.com/it-dennis/p/10508171.html .htm 和 .html 的区别 .htm 和 ...
- pycharm使用selenium之前
2.python安装好后,查看你的pycharm输出控制台,第一行就写了你所使用的python.exe的路径,如下图箭头处所示: 检查python使用的是不是你刚刚安装的,如果不是,换成你刚刚安装的p ...
- [mysql]You must reset your password using ALTER USER statement before executing this statement.
原因分析: MySQL版本5.6.6版本起,添加了password_expired功能,它允许设置用户的过期时间.这个特性已经添加到mysql.user数据表,但是它的默认值是”N”,可以使用ALTE ...