n個作業{0,1,2,…,n}在2臺機器上M1和M2組成的流水線上完成加工。每個作業加工的順序都是先在M1上加工,后在M2上加工。在兩臺機器上加工的時間分別為ai和bi。
目標:確定這n個作業的加工順序,使得從第一臺作業開始加工,到最后一個作業完成加工所需要的時間最少。
分析:
本題雖然用的是動態規劃,但是與其他題目不同,這道題目牽扯到一個新的知識點:
這道題,剛好把在M1上工作的時間看做是先行工序時間,M2上的工作時間看成后行工序時間。
如果某個作業的M1時間>M2時間,它就是后行工序;反之,就是先行工序時間。
這個基本原理來解流水作業問題,很簡單,很巧妙。程序中用到了結構體,也是為了程序的簡化,避免出現太多數組。
#include<stdio.h>
#include<iostream>
#include<algorithm>
#define n 6 //6個作業
using namespace std;
int M1[n]={2,7,6,4,6,8};
int M2[n]={5,3,2,7,9,2};
int c[n]={0}; //存放次序,注意:c[m]=k,意思是第m+1個執行的作業是k
typedef struct Node{
int time; //時間
int index; //來自第幾個作業
int position; //是先行工序還是后行工序
}Node;
bool cmp(Node x,Node y){
return x.time<y.time;
}
int main(){
Node node[n]; //設置n個Node型結構體,盛放n個作業
int first=0,end=n-1;
int time1=0,time2=0; //分別記錄在機器1 和 機器2 上的時間
for(int i=0;i<n;i++){ // 數組打底工作
node[i].index=i; //記錄一下當前這個node節點放的是哪個作業
if(M1[i]>M2[i]){
node[i].time=M2[i];
node[i].position=2; //后行工序
}
else{
node[i].time=M1[i];
node[i].position=1; //先行工序
}
}
//雖然把n個作業都賦值到了Node型結構體中,
//但是大小交錯,沒有順序,
//所以需要排序
sort(node,node+n,cmp);
//排完序后,把原本順序都亂了,先行、后行工作雖然交錯,但都已經從小到大排列了
//需要用c數組記錄執行順序,先行工序從前往后放,后行工序從后往前放
for(int i=0;i<n;i++){
if(node[i].position==1){ //先序
c[first]=node[i].index;
first++;
}
if(node[i].position==2){ //后序
c[end]=node[i].index;
end --;
}
}
time1=M1[c[0]];
time2=time1+M2[c[0]];
for(int i=1;i<n;i++){
time1+=M1[c[i]];
time2=time1>time2?time1+M2[c[i]]:time2+M2[c[i]];
}
printf("次序:\n");
for(int i=0;i<n;i++){
printf("%3d",c[i]+1);
}
putchar('\n');
printf("%d\n",time2);
return 0;
}
運行截圖