1. 問題描述
某工廠收到了 n 個產品的訂單,這 n 個產品分別在 A、B 兩個車間加工,並且必須先在 A 車間加工后才可以送到 B 車間。某個產品 i 在 A、B 兩車間加工的時間分別為 $A_i$、$B_i$。怎樣安排這 n 個產品的加工順序,才能使總的加工時間最短?這里所說的加工時間是指:從開始加工第一個產品到所有產品都加工完畢的時間。
2. 輸入格式
第一行僅一個數據 n(0 < n< 1000),表示產品的數量
接下來 n 個數據是表示這 n 個產品在 A 車間加工,各自所需要的時間(都是整數)
最后的 n 個數據是表示這 n 個產品在 B 車間加工,各自所需要的時間(都是整數)
3. 輸出格式
第一行一個數據,表示最短的加工時間
第二行是一種用時最短的產品加工率
4. 樣例輸入
5 3 5 8 7 10 6 2 1 4 9
5. 樣例輸出
34 1 5 4 2 3
6. 思路分析
直觀上,最優調度一定讓 $M_1$ 沒有空閑,$M_2$ 的空閑時間盡量短
Johnson 算法:設 $N_1$ 為 a < b 的作業集合,$N_2$ 為 a >= b 的作業集合,將 $N_1$ 的作業按 a 非減序排序,$N_2$ 中的作業按照 b 非增序排序,則 $N_1$ 作業接 $N_2$ 構成最優順序
7. 代碼
#include <iostream> using namespace std; int num; int a[1001],b[1001],c[1001],d[1001]; typedef struct DATA Data; struct DATA { int m[1001]; bool mark[1001]; }; Data data; void insertion_sort(int a[],int arr[],int len); int main() { ios::sync_with_stdio(false); cin>>num; int i = 1,sum = 0; for(;i <= num;i++) cin>>a[i]; for(i = 1;i <= num;i++) { cin>>b[i]; data.m[i] = min(a[i],b[i]); d[i] = i; if(data.m[i] == a[i]) data.mark[i] = false; else data.mark[i] = true; } insertion_sort(d,data.m,num); int j = num,k = 1; for(i = 1;i <= num;i++) { if(data.mark[d[i]] == true) c[j--] = d[i]; else c[k++] = d[i]; } for(i = 1;i <= num;i++) sum += a[c[i]]; sum += b[c[i-1]]; cout<<sum<<endl; for(i = 1;i <= num;i++) cout<<c[i]<<" "; return 0; } void insertion_sort(int a[],int arr[],int len) { for(int i=2; i<=len; i++) { int key=arr[i]; int key1 = a[i]; int j; for(j=i-1; j>=0 && key<arr[j]; j--) { arr[j+1] = arr[j]; a[j+1] = a[j]; } arr[j+1]=key; a[j+1] = key1; } }