ACM 任务分配问题

任务分配问题

Problem Description

现有 n 件任务和无限多台的机器,任务可以在机器上得到处理。每件任务的开始时间为 si,完成时间为 ei,[si, ei]为处理任务的时间范围。2 个任务重叠是指 2 个任务的时间范围有重叠。例如,[1, 4]与[2, 4]重叠,[1, 4]与[4, 7]重叠。一个可行的任务分配是指在分配中没有 2 件重叠的任务分配给同一台机器。
对于给定的 n 件任务,编程计算使用机器数最少的可行分配方案。

Input

第1行只有一个整数n(n<=1000,表示任务的总数。接下来有n行,每行2个整数si,ei分别表示任务的开始时间和完成时间,其中0<=si<=ei<10000.

Output

计算出的最少使用的机器数。

Sample Input

3
1 4 
2 5
5 7

Sample Output

2

Author

tianzuwei

思考:用N个任务,很多的机器,每一个任务有一个开始和结束的时间[si, ei],任务的完成时间是固定的,也是会有重叠的部分,也就是在3点的时候,可能有[1,4],[2,4]两个任务需要同时完成,现在问完成这么多的任务最少需要多少的机器。假如给每一个任务都分配一个机器的话,那么至多也就是需要N个机器,但是很明显的地方在于一台机器可以完成[1,3], [4,6] 等多个不重叠的任务,所以完成N个任务的最少机器,就是在某一个时间点上面任务重叠最多的所需要的机器。

程序大致解析: 以数组下标作为时间点,数组具体值作为重叠任务数,初始值为0,每输入一个任务,就在该任务完成的时间上面所有的时间节点+1,最后遍历所得的数组,找出最大的元素即所求。具体见下:

​
#include
#define maxx 10001
using namespace std;
int num[maxx];
int main()
{
    //freopen("in.txt","r",stdin);
    int n, i, mx, x, y, t;
    while(cin >> n)
    {
        t = 0;
        memset(num, 0 ,sizeof(num));
        for(i = 0; i < n; i++)
        {
            cin >> x >> y;
            for(x; x <= y; x++)
            num[x]++;
            if(t <= y) t = y;
        }
        mx = 0;
        for(i = 0; i <= t; i++)
        if(mx < num[i]) mx = num[i];
        cout << mx << endl;
    }
    fclose(stdin);
    
    return 0;
}

​

补充:后面学习当中,发现更加好的算法,上面的算法时间复杂度为O(n^2),可以用差分数组的思想,优化到O(n)的时间复杂度。见下面代码:

#include
using namespace std;
#define INF 0x3f3f3f3f
const int N = 100000 + 10;
int m, q;
int a[N], d[N], sum[N];
int main() 
{
	//freopen("in.txt", "r", stdin);
    int n;
    while (scanf("%d", &n) != EOF) 
	{
        memset(a, 0, sizeof(a));//初始化都为0
        int l, r;
        memset(d, 0, sizeof(d));
        d[1] = a[1];//特殊处理第一个数
        for (int i = 0; i < n; i++) 
		{
            scanf("%d%d", &l, &r);
            d[l] += 1;
            d[r+1] -= 1;
        }
        memset(sum, 0, sizeof(sum));
        for (int i = 1; i <= n; ++i) 
		{
            sum[i] = sum[i-1] + d[i]; //求d[i]前缀和, 也就是修改后的a[i]
        }
        int maxn = 0;
        for (int i = 1; i <= n; ++i)
		{
          if(maxn < sum[i]) maxn = sum[i];
        }
        cout << maxn << endl;
    }
fclose(stdin);
    return 0;
}

 

你可能感兴趣的:(ACM)