非單位時間任務安排問題[動態規划]


問題&數據輸入&數據輸出:

 

 分析:

  首先將任務按其截止時間非減序排序。

  對任務 1 , 2 , …… , i,如果截止時間為 d ,則最小誤時懲罰為 p( i , d ) 。

  其中 p( i , d ) = min{ p(i-1, d)+wi  ,  p(i-1, min{d, di}-ti) }

   p(i-1, d)+wi 表示決定不做第 i 個任務,p(i-1, min{d, di}-ti) 表示決定要做第 i 個任務,這時必須在第 i 個任務的截至時間前做完它(即 min{d, di}-ti )

  

思路:

  先將任務集按照結束時間非遞減排序。

  設置數組p[ ][ ]來保存 p( i , d )的結果(本算法的局限性:時間只能為整數值)。

  對於第一個任務來說,如果時間少於它需要執行的時間 t,則會遭受懲罰——p[1][ 0 ~ tasks[1].t ]=tasks[i].w;

            時間夠則不然——p[1][ 0 - tasks[1].t ]=0。

  對於第 i 個任務 的任務來說( i 取 2 - n),就如果時間少於它需要執行的時間 t,則不能執行它了,只能放棄——p[ i ][ 0 ~ tasks[1].t ]=p(i-1, d)+wi;

                   如果時間夠,則看是執行了好還是不執行好——p[ i ][  tasks[1].t ~ maxTime ] = min{ p(i-1, d)+wi  ,  p(i-1, min{d, di}-ti) }。

 

代碼:

  

#include<iostream>
#include<fstream>
#define Max 99
using namespace std;

struct Task {
    int t; //完成任務需要的時間
    int d; //截止時間
    int w; //誤時懲罰
};


void quickSort(Task s[], int l, int r)
{//快速排序,不是重點
    if (l < r)
    {
        int i = l, j = r;
        Task x = s[l];
        while (i < j)
        {
            while (i < j && s[j].d >= x.d)
                j--;
            if (i < j)
                s[i++] = s[j];

            while (i < j && s[i].d < x.d)
                i++;
            if (i < j)
                s[j--] = s[i];
        }
        s[i] = x;
        quickSort(s, l, i - 1);
        quickSort(s, i + 1, r);
    }
}

int min(int a, int b)
{return (a > b) ? b : a;
}

void main()
{
    ifstream input("input.txt");
    ofstream output("output.txt");

    int n;
    input >> n;
    Task *tasks = new Task[n + 1];

    for (int i = 1; i <= n; i++)
    {
        input >> tasks[i].t >> tasks[i].d >> tasks[i].w;
    }
    //按截至時間非遞減排序
    quickSort(tasks, 1, n);

    int p[500][500];

    //先初始化
    for (int i = 1; i <= n; i++)
    {
        for (int j = 0; j < tasks[n].d; j++)
        {
            p[i][j] = Max;
        }
    }

    //任務 1,沒有更前面的任務了,單獨討論
    for (int i = 0; i <= tasks[n].d; i++)
    {
        if (i < tasks[1].t)//如果沒給夠時間
        {
            p[1][i] = tasks[1].w;//
        }
        else
        {
            p[1][i] = 0;
        }
    }

    for (int i = 2; i <= n; i++)
    {
        for (int j = 0; j <= tasks[n].d; j++)
        {
            int a = p[i - 1][j] + tasks[i].w;
            int b = p[i - 1][min(j, tasks[i].d) - tasks[i].t];
            if (j < tasks[i].t)
            {
                p[i][j] = a;
            }
            else
            {
                if (a < b)
                    p[i][j] = a;
                else
                    p[i][j] = b;
            }
        }
    }

    cout << p[n][tasks[n].d] << endl;
    cin >> n;

    input.close();
    output.close();
}

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM