申請SAE

如果您發現本博客的外觀很難看,那是因為部分外觀文件被中國.國家.防火.牆屏.蔽所致!
請翻~牆!

我的Wordpress博客的地址: http://zhuyf.tk/

2011年10月25日 星期二

NOIP2006提高組 作業調度方案 jsp 解題報告

 【問題描述】
我們現在要利用 m 臺機器加工 n 個工件,每個工件都有 m 道工序,每道工序都在不同的指定的機器上完成。每個工件的每道工序都有指定的加工時間。
每 個工件的每個工序稱爲一個操作,我們用記號 j-k 表示一個操作,其中 j 爲 1 到 n 中的某個數字,爲工件號; k 爲 1 到 m 中的某個數字,爲工序號,例如 2-4 表示第 2 個工件第 4 道工序的這個操作。在本題中,我們還給定對於各操作的一個安排順序。
例 如,當 n=3 , m=2 時,“ 1-1 , 1-2 , 2-1 , 3-1 , 3-2 , 2 -2 ” 就是一個給定的安排順序,即先安排第 1 個工件的第 1 個工序,再安排第 1 個工件的第 2 個工序,然後再安排第 2 個工件的第 1 個工序,等等。
一方面,每個操作的安排都要滿足以下的兩個約束條件。
(1) 對同一個工件,每道工序必須在它前面的工序完成後才能開始;
(2) 同一時刻每一臺機器至多只能加工一個工件。
另一方面,在安排後面的操作時,不能改動前面已安排的操作的工作狀態。
由於同一工件都是按工序的順序安排的,因此,只按原順序給出工件號,仍可得到同樣的安排順序,於是,在輸入數據中,我們將這個安排順序簡寫爲“ 1 1 2 3 3 2 ” 。
還要注意,“安排順序”只要求按照給定的順序安排每個操作。不一定是各機器上的實際操作順序。在具體實施時,有可能排在後面的某個操作比前面的某個操作先完成。
例如,取 n=3,m=2 ,已知數據如下:
工件號
機器號 / 加工時間
工序 1
工序 2
1
1/3
2/2
2
1/2
2/5
3
2/2
1/4

則對於安排順序“ 1 1 2 3 3 2 ” ,下圖中的 兩個實施方案都是正確的。但所需要的總時間分別是 10 與 12 。
當 一個操作插入到某臺機器的某個空檔時(機器上最後的尚未安排操作的部分也可以看作一個空檔),可以靠前插入,也可以靠後或居中插入。爲了使問題簡單一些, 我們約定:在保證約束條件( 1 )( 2 )的條件下,儘量靠前插入。並且,我們還約定,如果有多個空檔可以插入,就在保證約束條件( 1 )( 2 )的條件下,插入到最前面的一個空檔。於是,在這些約定下,上例中的方案一是正確的,而方案二是不正確的。
顯然,在這些約定下,對於給定的安排順序,符合該安排順序的實施方案是唯一的,請你計算出該方案完成全部任務所需的總時間。

【輸入文件】
輸入文件 jsp.in 的第 1 行爲兩個正整數,用一個空格隔開:m n
(其中 m ( <20 )表示機器數, n ( <20 )表示工件數)
第 2 行: 個用空格隔開的數,爲給定的安排順序。
接下來的 2n 行,每行都是用空格隔開的 m 個正整數,每個數不超過 20 。
其中前 n 行依次表示每個工件的每個工序所使用的機器號,第 1 個數爲第 1 個工序的機器號,第 2 個數爲第 2 個工序機器號,等等。
後 n 行依次表示每個工件的每個工序的加工時間。
可以保證,以上各數據都是正確的,不必檢驗。

【輸出文件】
輸出文件 jsp.out 只有 一個正整數,爲最少的加工時間。

【輸入輸出樣例】
jsp.in
2 3
1 1 2 3 3 2
1 2
1 2
2 1
3 2
2 5
2 4
jsp.out
10

【分析】
作為NOIP2006的第三題,題目又這麼長,真是很考驗人的耐心~
不過如果把題讀懂了,發現該題十分簡單。
一下題解來自BYVoid大牛的博客:
http://www.byvoid.com/blog/noip-allsolutions/

做這道題關鍵在於理解題意。這道題讓我想起了流水作業調度的Johnson算法,雖然與這道題無關。
提示幾點
1、每個工件的每個工序對應着不同的機器。
2、一個工件必須按照加工順序加工。
3、把每個機器看成一個時間軸,每個時間對應着加工一個工件,或者爲空閒狀態。
4、題中的算法是給定的貪心策略,不需要構造,只要模擬。
由於數據很小,把每個機器的時間軸用布爾數組表示,true爲該時間有工件在加工,false爲空閒。
按照給定的順序,一件一件得往時間軸上插入,每個工件插入的位置必須在前面的工序都完成以後的時間斷插入。每次插入掃描一遍時間軸數組,找到最前面一個。
其實題中所給的圖已經一目瞭然了。理解題意以後,會發現這是NOIP2006最簡單的題。

【我的代碼】
//NOIP2006-jsp
#include <fstream>
#include <iostream>
#include <cstdio>
#include <cstdlib>
using namespace std;
ifstream fin("jsp.in");
ofstream fout("jsp.out");
const int MT=1000;
const int MAX=21;
int M,N;//M:機器數,N:工件數
int S[MAX*MAX];

class JSP
{
public:
    int Mach[MAX];
    int Time[MAX];
    int Start;
    int Todo;
    JSP()
    {
        for (int i=1;i<=MAX;i++)
        {
            Mach[i]=0;
            Time[i]=0;
        }
        Start=0;
        Todo=1;
    }
}P[MAX];

class Machine
{
public:
    bool Use[1001];//true:被佔用,false:空閒.
    Machine()
    {
        for(int i=0;i<=MT;i++)
        Use[i]=false;
    }
}U[MAX];

void  init()
{
    fin>>M>>N;
    int i,j;
    for (i=1;i<=M*N;i++)
        fin>>S[i];
   
    for (i=1;i<=N;i++)
        for (j=1;j<=M;j++)
            fin>>P[i].Mach[j];
   
    for (i=1;i<=N;i++)
        for (j=1;j<=M;j++)
            fin>>P[i].Time[j];
    return;
}

void Tanxin()
{
    int i,j,k;//臨時變量
    int c;//當前工件
    int t;//當前工序的耗時
    int m;//當前工序的機器
    bool brin;//是否可以在當前時間插入機器
    for(i=1;i<=M*N;i++)
    {
        c=S[i];
        m=P[c].Mach[P[c].Todo];
        t=P[c].Time[P[c].Todo];
        for (j=P[c].Start;j<=MT;j++)
        {
            brin=true;
            for (k=j;k<=j+t-1;k++)
            {
                if(U[m].Use[k])
                {
                    brin=false;
                    break;
                }
            }
           
            if (brin)
            {
                for (k=j;k<=j+t-1;k++)
                    U[m].Use[k]=true;
                P[c].Start=j+t;
                P[c].Todo++;
                break;
            }
        }
    }
    return;
}

int main()
{
    int maxn=0;
    init();
    Tanxin();
    for (int i=1;i<=M;i++)
    {
        for (int j=MT-1;j>=0;j--)
        {
            if (U[i].Use[j])
            {
                if (j>maxn)
                    maxn=j;
                break;
            }
        }
    }
    fout<<++maxn<<endl;
    return 0;
}

正在连接评测机...

已连接到评测机
GRID 1
名称 Flitty
系统版本 1.00
备注 COGS 1号评测机 Flitty
正在编译...
编译成功

测试点 结果 得分 运行时间 内存使用 退出代码
1 正确 10 0.015 s 301 KB 0
2 正确 10 0.001 s 301 KB 0
3 正确 10 0.000 s 301 KB 0
4 正确 10 0.001 s 301 KB 0
5 正确 10 0.001 s 301 KB 0
6 正确 10 0.001 s 301 KB 0
7 正确 10 0.001 s 301 KB 0
8 正确 10 0.001 s 301 KB 0
9 正确 10 0.001 s 301 KB 0
10 正确 10 0.001 s 301 KB 0
运行完成
运行时间 0.020 s
平均内存使用 301 KB
测试点通过状况 AAAAAAAAAA
得分:100
恭喜你通过了全部测试点!

沒有留言:

張貼留言