1. 程式人生 > >最優排程問題

最優排程問題

【問題描述】
用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 個作業需要的處理時間。
【輸出格式】
一個數表示最短處理時間
【樣例輸入】
62
5 7 10 5 2
3 8 4 11 3 4
【樣例輸出】

15

首先想到揹包問題解法:DP。
但是我懶得想它的狀態轉移方程,於是來一發記憶化搜尋。
對當前任務而言,無非放在A機器與B機器執行,
用ta記錄A時間,用tb記錄B時間,
則狀態:
dfs(x+1,ta+tia[x],tb);//放在A執行
dfs(x+1,ta,tb+tib[b]);//放在B執行

貼程式碼:

#include<iostream>
#include<cstdio>
using namespace std;
int tia[310]={0};
int tib[310]={0};
bool steps[305][502][550];
void
dfs(int x,int ta,int tb); int n,maxmin=2100000000; int main() { int a; cin>>n; for (a=1;a<=n;a++) scanf("%d",&tia[a]); for (a=1;a<=n;a++) scanf("%d",&tib[a]); dfs(1,0,0); cout<<maxmin; return 0; } void dfs(int x,int ta,int tb) { if (steps[x][ta%501][tb%549]) return ; //記憶化,判斷當前位是否被搜
steps[x][ta%501][tb%549]=1; //標記被搜 if (x>n) { maxmin=min( max(ta,tb), maxmin ); return ; } dfs(x+1,ta+tia[x],tb); dfs(x+1,ta,tb+tib[x]); }

搜尋改記憶化很簡單,其實也就2句話:判斷狀態是否重複,標記狀態已使用。
動態規劃本質是不重複地遍歷所有狀態,而記憶化搜尋也可以做到,
故記憶化搜尋效率與DP相近。
但當搜尋裡帶有迴圈時,記憶化搜尋的效率要低出DP很多。

相關推薦

no