1. 程式人生 > >任務安排

任務安排

題目描述

【問題描述】

N個任務排成一個序列在一臺機器上等待完成(順序不得改變),這N個任務被分成若干批,每批包含相鄰的若干任務。從時刻0開始,這些任務被分批加工,第i個任務單獨完成所需的時間是Ti。在每批任務開始前,機器需要啟動時間S,而完成這批任務所需的時間是各個任務需要時間的總和(同一批任務將在同一時刻完成)。每個任務的費用是它的完成時刻乘以一個費用係數Fi。請確定一個分組方案,使得總費用最小。

例如:S=1;T={1,3,4,2,1};F={3,2,3,3,4}。如果分組方案是{1,2}、{3}、{4,5},則完成時間分別為{5,5,10,14,14},費用C={15,10,30,42,56},總費用就是153。

【輸入檔案】

第一行是n(1<=n<=5000);

第二行是s(0<=s<=50)。

下面n行每行有一對數,分別為Ti和Fi,均為不大於100的正整數,表示第i個任務單獨完成所需的時間是Ti及其費用係數Fi。

【輸出檔案】

一個數,最小的總費用。

【輸入輸出樣例】

輸入:

5

1

1 3

3 2

4 3

2 3

1 4

輸出:

153

錯誤解法:設f[i]表示前i個完成所需的最小花費,g[i]表示前i個取得最小花費時分的組數,則f[i]=min{f[j]+s*(g[j]+1)*t*p·}

因為方案有後效性,分不同的組對後面的花費有影響。

#include<bits/stdc++.h>
#define f(i,l,r) for(i=(l);i<=(r);i++)
#define ff(i,r,l) for(i=(r);i>=(l);i--)
using namespace std;
const int MAXN=5005,INF=1e9;
int n,S;
struct Edge{
	int t,f;
}a[MAXN];
int f[MAXN];
int main()
{
	ios::sync_with_stdio(false);
	memset(f,60,sizeof(f));
	int ans=INF;
	int i,j,k;
	cin>>n>>S;
	f(i,1,n){
		cin>>a[i].t>>a[i].f;
		a[i].t+=a[i-1].t;
		a[i].f+=a[i-1].f;
	}
	f[0]=0;
	f(i,1,n){
		f(j,0,i-1){
			if(f[i]>f[j]+a[i].t*(a[i].f-a[j].f)+S*(a[n].f-a[j].f)){
				f[i]=f[j]+a[i].t*(a[i].f-a[j].f)+S*(a[n].f-a[j].f);
			}
		}
	}
	cout<<f[n]<<endl;
	return 0;
}