机器上有N个需要处理的任务,它们构成了一个序列。这些任务被标号为1到N,因此序列的排列为1,2,3...N。这N个任务被分成若干批,每批包含相邻的若干任务。从时刻0开始,这些任务被分批加工,第i个任务单独完成所需的时间是Ti。在每批任务开始前,机器需要启动时间S,而完成这批任务所需的时间是各个任务需要时间的总和。注意,同一批任务将在同一时刻完成。每个任务的费用是它的完成时刻乘以一个费用系数Fi。请确定一个分组方案,使得总费用最小。
标签:main type 机器 html out using algorithm tput long
#include <iostream> #include <cstdio> #include <cstring> #include <algorithm> #include <cmath> using namespace std; const int N=1e6+5; typedef long long ll; inline int read(){ char c=getchar();int x=0,f=1; while(c<‘0‘||c>‘9‘){if(c==‘-‘)f=-1;c=getchar();} while(c>=‘0‘&&c<=‘9‘){x=x*10+c-‘0‘;c=getchar();} return x*f; } int n,s; int q[N],head,tail; ll t[N],p[N],f[N]; //inline double slope(int j,int k){ // return (double)(f[k]-f[j])/(double)(p[k]-p[j])-s; //} void dp(){ for(int i=1;i<=n;i++){ int l=0,r=tail; // while(l<r){ // int mid=(l+r)>>1; // if(slope(q[mid],q[mid+1])>=(double)t[i]) r=mid; // else l=mid+1; // } while (l<r){ long long mid=(l+r)/2; if (f[q[mid+1]]-f[q[mid]]>=(s+t[i])*(p[q[mid+1]]-p[q[mid]])) r=mid; else l=mid+1; } int j=q[l]; f[i]=f[j]+t[i]*(p[i]-p[j])+s*(p[n]-p[j]); // while(head<tail&&slope(q[tail-1],q[tail])>slope(q[tail],i)) tail--; // q[++tail]=i; while(head<tail&&(f[i]-f[q[tail]])*(p[q[tail]]-p[q[tail-1]])<=(f[q[tail]]-f[q[tail-1]])*(p[i]-p[q[tail]])) tail--; q[++tail]=i; } printf("%lld",f[n]); } int main(){ //freopen("in.txt","r",stdin); n=read();s=read(); for(int i=1;i<=n;i++) t[i]=t[i-1]+read(),p[i]=p[i-1]+read(); dp(); }
BZOJ 2726: [SDOI2012]任务安排 [斜率优化DP 二分 提前计算代价]
标签:main type 机器 html out using algorithm tput long
原文地址:http://www.cnblogs.com/candy99/p/6262247.html