非单位时间任务安排问题

Posted JackGo

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了非单位时间任务安排问题相关的知识,希望对你有一定的参考价值。

问题&数据输入&数据输出:

 

 分析:

  首先将任务按其截止时间非减序排序。

  对任务 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();
}

 

以上是关于非单位时间任务安排问题的主要内容,如果未能解决你的问题,请参考以下文章

6.15Alpha

java 每间隔一段时间执行一段代码

6.12冲刺博客

6.14冲刺博文

Fragment 中的计划任务将 getActivity 返回为 null

贪心算法----区间覆盖问题(POJ2376)