Batch Scheduling

Batch Scheduling
There is a sequence of N jobs to be processed on one machine. The jobs are numbered from 1 to N, so that the sequence is 1,2,..., N. The sequence of jobs must be partitioned into one or more batches, where each batch consists of consecutive jobs in the sequence. The processing starts at time 0. The batches are handled one by one starting from the first batch as follows. If a batch b contains jobs with smaller numbers than batch c, then batch b is handled before batch c. The jobs in a batch are processed successively on the machine. Immediately after all the jobs in a batch are processed, the machine outputs the results of all the jobs in that batch. The output time of a job j is the time when the batch containing j finishes. 


A setup time S is needed to set up the machine for each batch. For each job i, we know its cost factor Fi and the time Ti required to process it. If a batch contains the jobs x, x+1,... , x+k, and starts at time t, then the output time of every job in that batch is t + S + (T x + T x+1 + ... + T x+k). Note that the machine outputs the results of all jobs in a batch at the same time. If the output time of job i is Oi, its cost is Oi * Fi. For example, assume that there are 5 jobs, the setup time S = 1, (T1, T2, T3, T4, T5) = (1, 3, 4, 2, 1), and (F1, F2, F3, F4, F5) = (3, 2, 3, 3, 4). If the jobs are partitioned into three batches {1, 2}, {3}, {4, 5}, then the output times (O1, O2, O3, O4, O5) = (5, 5, 10, 14, 14) and the costs of the jobs are (15, 10, 30, 42, 56), respectively. The total cost for a partitioning is the sum of the costs of all jobs. The total cost for the example partitioning above is 153. 


You are to write a program which, given the batch setup time and a sequence of jobs with their processing times and cost factors, computes the minimum possible total cost. 
Input
Your program reads from standard input. The first line contains the number of jobs N, 1 <= N <= 10000. The second line contains the batch setup time S which is an integer, 0 <= S <= 50. The following N lines contain information about the jobs 1, 2,..., N in that order as follows. First on each of these lines is an integer Ti, 1 <= Ti <= 100, the processing time of the job. Following that, there is an integer Fi, 1 <= Fi <= 100, the cost factor of the job.
Output
Your program writes to standard output. The output contains one line, which contains one integer: the minimum possible total cost.
Sample Input
5
1
1 3
3 2
4 3
2 3
1 4
Sample Output

153

題意:n個工作,編號爲1到n,現在要把工作分成若干個連續但是不相交的區間。從第一個數所在的區間開始,依次完成每個區間的工作。假設某個區間包含的工作爲(i到j),那麼完成這個區間的工作要花的時間爲(s+Ti+...Tj),s爲啓動時間一個常量,Ti爲完成第i個工作要花的時間。設T爲完成前i-1個工作所花的時間,那麼完成這個區間的花費爲(T+s+Ti+...Tj)*(Fi+...Fj)。求完成n個工作的最小花費。

思路:最開始用dp[i]表示1到i的最小花費,然而方程式化簡出來後發現無法套到斜率優化裏面%>_<%,最後發現其實dp[i]表示i到n就解決問題了( ⊙ o ⊙ )dp[i]=min(dp[j]+(s+sumt[i]-sumt[j])*sumf[i])(在i後面的所有人都會因爲i造成花費,所以*sumf[i],而表示1到i時需要*(sum[i]-sum[j])就造成了展開後無法化簡到斜率的形式o(>﹏<)o)然後按普通套路乘開化簡,轉成函數。O(∩_∩)O~~

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstdlib>
#include<queue>
#include<vector>
#include<cmath>
#include<cstring>
#include<deque>
using namespace std;
const int N=12000+10;
int n,s,head,tail,sum[N],c[N],dp[N];
struct node{
	int x,y,pos;
	node(){}
	node(int a,int b,int c){
		x=a,y=b,pos=c;
	}
	node operator - (const node &a)const{
		return node(x-a.x,y-a.y,0);
	}
	int operator * (const node &a)const{
		return x*a.y-y*a.x;
	}
}now,q[N<<2];
bool check(node a,node b,int c){
	return (b.y-a.y)<c*(b.x-a.x);
}
int main(){
    while(~scanf("%d%d",&n,&s)){
		for(int i=1;i<=n;i++)
			scanf("%d%d",&sum[i],&c[i]);
		for(int i=n;i>=1;i--)
			sum[i]+=sum[i+1],c[i]+=c[i+1];
		memset(dp,0,sizeof(dp));
		head=tail=0;
		q[tail++]=node(0,0,n+1);
		for(int i=n;i>=1;i--){
			while(head+1<tail&&check(q[head],q[head+1],c[i]))
				head++;
			dp[i]=dp[q[head].pos]+(s+sum[i]-sum[q[head].pos])*c[i];
			now=node(sum[i],dp[i],i);
			while(head+1<tail&&(q[tail-1]-q[tail-2])*(now-q[tail-1])<=0)
				tail--;
			q[tail++]=now;
		}
		printf("%d\n",dp[1]);
	}
}


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章