1. 程式人生 > >南郵 OJ 1220 獨立任務最優排程問題

南郵 OJ 1220 獨立任務最優排程問題

獨立任務最優排程問題

時間限制(普通/Java) : 1000 MS/ 3000 MS          執行記憶體限制 : 65536 KByte
總提交 : 164            測試通過 : 35 

比賽描述

用2臺處理機A和B處理n個作業。設第i個作業交給機器A處理時需要時間ai,若由機器B來處理,則需要時間bi。由於各作業的特點和機器的效能關係,很可能對於某些i,有ai>bi,而對於某些j,j≠i,有aj>bj。既不能將一個作業分開由2臺機器處理,也沒有一臺機器能同時處理2個作業。設計一個動態規劃演算法,使得這2臺機器處理完這n個作業的時間最短(從任何一臺機器開工到最後一臺機器停工的總時間)。研究一個例項:

(a1,a2,a3,a4,a5,a6)=(2,5,7,10,5,2);(b1,b2,b3,b4,b5,b6)=(3,8,4,11,3,4)。

對於給定的2臺處理機A和B處理n個作業,找出一個最優排程方案,使2臺機器處理完這n個作業的時間最短。

輸入

輸入的第1行是1個正整數n,表示要處理n個作業。接下來的2行中,每行有n個正整數,分別表示處理機A和B處理第i個作業需要的處理時間。

輸出

輸出最短處理時間。

樣例輸入

6
2 5 7 10 5 2
3 8 4 11 3 4

樣例輸出

15

提示

題目來源

演算法設計與實驗題解


/*
問題分析:

此題目可以使用動態規劃來做。難點是如何構造動態規劃演算法。找出最優子結構和遞推公式。

有兩種構造方法:

1.t[i][j][k],表示機器A花費小於等於i的時間,機器B花費小於等於j的時間能夠完成前K個任務,取值為bool型別

遞推公式如下:t[i][j][k]=t[i-a[k]][j][k-1]|t[i][j-b[k]][k-1],這種構造方法需要一個三維陣列,空間和時間複雜度都相對較高

2.t[i][j],表示完成前i個任務,機器A花費小於等於j的時間的前提下,機器B所需要的最小時間。

遞推公式如下:t[i][j]=min{t[i-1][j-a[i]],t[i-1][j]+b[i]},這種方法時間和空間複雜度相較於第一種方法較低。
							|任務k由A完成	|任務k由B完成
*/

#include<iostream>
using namespace std;

int task_schedule(int *a,int *b,int n){
	int i,j,sum=0,min=1<<30;
	for(i=0;i<n;++i){
		sum += a[i];
	}
	int **t=(int **)malloc(sizeof(int*)*(n+1));		//把t構造成int t[n+1][sum+1]
	for(i=0;i<=n;++i){
		t[i] = (int *)malloc(sizeof(int)*(sum+1));
		memset(t[i],0,sizeof(int)*(sum+1));
	}
	for(i=1;i<=n;++i){
		for(j=0;j<=sum;++j){
			if(j<a[i-1]){
				t[i][j] = t[i-1][j]+b[i-1];
			}else if(t[i-1][j-a[i-1]]>=(t[i-1][j]+b[i-1])){
				t[i][j] = t[i-1][j]+b[i-1];
			}else{
				t[i][j] = t[i-1][j-a[i-1]];
			}
		}
	}
	for(i=0;i<=sum;++i){
		j = t[n][i]>i ? t[n][i] : i;
		if(min>j){
			min = j;
		}
	}
	return min;
}

int main(){
	int n,i;
	cin>>n;
	int *a=new int[n];
	int *b=new int[n];
	for(i=0;i<n;++i){
		cin>>a[i];
	}
	for(i=0;i<n;++i){
		cin>>b[i];
	}
	cout<<task_schedule(a,b,n)<<endl;
}