1. 程式人生 > >【貪心】加工生產排程(雙機排程貪心問題)

【貪心】加工生產排程(雙機排程貪心問題)

問題 D: 【貪心】加工生產排程

時間限制: 1 Sec  記憶體限制: 64 MB
提交: 41  解決: 21
[提交] [狀態] [討論版] [命題人:外部匯入]

題目描述

有n個部件需在A、B機器上加工,每個工件都必須經過先A後B兩道工序。
已知:部件i在A、B機器上的加工時間分別為ai,bi。
問:如何安排n個工件的加工順序,才能使得總加工時間最短?

輸入

第1行僅一個整數n (0<n<1000),表示產品的數量;
第2行n個整數,表示這n個產品在A車間加工各自所要的時間(都是整數);
第3行n個整數,表示這n個產品在B車間加工各自所要的時間(都是整數)。

輸出

只有一個數,表示最少的加工時間;

樣例輸入

5
3 5 8 7 10
6 2 1 4 9

樣例輸出

34

[提交][狀態]

【分析】

此題貪心策略不好理解。

(1)考慮只有兩個任務。

機器A一定無空閒直到結束,而機器B必有一段空閒,即剛開始等待A給他第一個任務,我們要讓第一個任務在機器A上儘量早結束,所以讓ai小的先執行。  這樣就可以了嗎? 給出一組樣例:任務1={4,1},任務2={5,3},我們發現,若先執行任務1,總時間為12,若先執行2再執行1,總時間為10。這是因為任務1的bi太小,其執行完後機器B留下一段時間的空閒。  可見,我們不僅要縮小一開始機器B的等待時間,還要縮小過程中機器B的空閒時間。 縮小空閒時間的方法就是讓bi小的儘量留到後面再加工。 綜上所述,得出結論

:需要考慮兩個條件:①ai小的靠前②bi小的靠後。怎樣決定一個任務靠前還是靠後呢?任務本身做一個權衡比較ai與bi的大小,遵循小的那一個的條件。至此即可解決兩個任務的情況。

(2)考慮多個任務

把所有任務分為兩類,1類ai<bi,2類ai>bi。至於ai=bi放在哪一類均可,無影響,就因為ai=bi,安排在任意位置,對結果的貢獻是不變的。根據(1)中的結論,1類可按ai排序,2類按bi排序,安排後的結果一定是1類全部執行完再執行2類。

還有一種理解方式,可能不太嚴謹的二分思想:假設n個任務分成兩個部分,每一部分內部已經按最優策略安排好,這兩部分就可以看做是兩個單獨的任務了,下一步按(1)處理即可。

【程式碼】

#include<bits/stdc++.h>
using namespace std;
struct node{
    int a,b,flag;
}item[1010];
bool cmp(node x,node y)
{
    if(x.flag==y.flag)
    {
        if(x.flag==0)
            return x.a<y.a;
        return x.b>y.b;
    }
    return x.flag<y.flag;
}
int main()
{
    int n; scanf("%d",&n);
    for(int i=0;i<n;i++)scanf("%d",&item[i].a);
    for(int i=0;i<n;i++)scanf("%d",&item[i].b);
    for(int i=0;i<n;i++)item[i].flag=(item[i].a<item[i].b?0:1);
    sort(item,item+n,cmp);
    int A=0,B=0;
    for(int i=0;i<n;i++)
    {
        A+=item[i].a;
        B=max(B,A)+item[i].b;
    }
    printf("%d\n",B);
}