bzoj 2726: [SDOI2012]任务安排

Posted qt666

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了bzoj 2726: [SDOI2012]任务安排相关的知识,希望对你有一定的参考价值。

Description

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

Input

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

Output

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

Sample Input

5 1
1 3
3 2
4 3
2 3
1 4

Sample Output

153

HINT

Source

 

这个题一开始想着去处理一个人等了多长时间

然后就会发现等的时间是和前面分了多少批有关的,这样的话我们需要用二维状态表示到这个点,前面分了多少批

这样暴力会很萎

这时候我们会回想起一个叫做修车的题目,他对于每个点的处理相当于是这个点让后面的人多等了多久

那我们可以通过同样的方式思考,每分了一批其实就是让后面的所有人多等了一个S的时间,其余的并不影响

那么我们可以推出一维的状态

f[i]=min(f[j]+s*(F[n]-F[j])+T[i]*(F[i]-F[j]));

对于前百分之60的数据,T为正数,满足决策单调性,可以二分栈,但我懒得打了,就在codevs上AC了一个弱化版的n^2;

斜率优化在下面

// MADE BY QT666
#include<cstdio>
#include<algorithm>
#include<cmath>
#include<iostream>
#include<queue>
#include<set>
#include<cstdlib>
#include<cstring>
#include<string>
#include<ctime>
#define lson num<<1
#define rson num<<1|1
#define int long long
using namespace std;
typedef long long ll;
const int N=100050;
int gi()
{
  int x=0,flag=1;
  char ch=getchar();
  while(ch<‘0‘||ch>‘9‘){if(ch==‘-‘) flag=-1;ch=getchar();}
  while(ch>=‘0‘&&ch<=‘9‘) x=x*10+ch-‘0‘,ch=getchar();
  return x*flag;
}
int f[N],t[N],F[N],s,n;
int cal(int j,int i){
	return f[j]+s*(F[n]-F[j])+t[i]*(F[i]-F[j]);
}
main()
{
	n=gi(),s=gi();
	for(int i=1;i<=n;i++) t[i]=gi()+t[i-1],F[i]=gi()+F[i-1];
	for(int i=1;i<=n;i++){
		f[i]=cal(0,i);
		for(int j=1;j<i;j++){
			f[i]=min(f[i],cal(j,i));
		}
	}
	printf("%lld",f[n]);
}

 

我们来推一推斜率方程:

f[j]+s*(F[n]-F[j])+T[i]*(F[i]-F[j)<=f[k]+s*(F[n]-F[k])+T[i]*(F[i]-F[k]);
f[j]+s*F[n]-s*F[j]+T[i]*F[i]-T[i]*F[j]<=f[k]+s*F[n]-s*F[k]+T[i]*F[i]-T[i]*F[k];
f[j]-s*F[j]-T[i]*F[j]<=f[k]-s*F[k]-T[i]*F[k];
令Y(j)=f[j]-s*F[j];
令X(j)=F[j];
则变为:
Y(j)-T[i]*X(j)<=Y(k)-T[i]*X(k);
T[i]*(X(k)-X(j))<=Y(k)-Y(j);
若X(k)>=X(j):T[i]<=(Y(k)-Y(j))/(X(k)-X(j));
若X(k)<=X(j);T[i]>=(Y(k)-Y(j))/(X(k)-X(j));
因为F值都是正的,所以X(k)>=X(j);横坐标单调;
所以T[i]<=(Y(k)-Y(j))/(X(k)-X(j));
然而斜率T[i]不是单调的

然后我就不会做了

以上是关于bzoj 2726: [SDOI2012]任务安排的主要内容,如果未能解决你的问题,请参考以下文章

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

bzoj 2726 [SDOI2012]任务安排(斜率DP+CDQ分治)

bzoj 2726: [SDOI2012]任务安排

bzoj2726 [SDOI2012]任务安排

BZOJ 2726: [SDOI2012]任务安排( dp + cdq分治 )

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