GHOJ 681 最佳调度问题

题目描述

  假设有n个任务由k个可并行工作的机器完成。完成任务i需要的时间为ti。试设计一个算法找出完成这n个任务的最佳调度,使得完成全部任务的时间最早。对任意给定的整数n和k,以及完成任务i需要的时间为ti,1≤i≤n。编程计算完成这n个任务的最佳调度。

 

输入格式

  第一行,两个正整数n和k。

  第二行,n个正整数,是完成n个任务需要的时间。

输出格式

  一行,一个整数,完成全部任务的最早时间。

 

输入样例

7 3

2 14 4 16 6 5 3

输出样例

17

题解

  容易想到,我们按照顺序对每一个工作放在每一个机器上的情况进行搜索。但是显然会tle,那就需要我们进行剪枝。

  首先,我们设当前情况下的时间为$t$,当前已知的最优解为$ans$,则当$t geqslant ans$时,我们可以直接return。

  这个时候我们想,为了尽可能多剪,我们可以对每个工作进行降序排序,然后从时间长的开始搜。

  其实还有一个剪枝。假设机器$i$和机器$j$当前运作的时间相同,那实际上我们只用搜当前工作放在机器$i$上的情况就好了。

#include <iostream>
#include <algorithm>

#define MAX_N (20 + 5)
#define MAX_M (20 + 5)

using namespace std;

int n, m;
int a[MAX_N];
int b[MAX_M];
int ans = 0x7f7f7f7f;

void DFS(int x, int t)
{
    if(t >= ans) return;
    if(!x)
    {
        ans = t;
        return;
    }
    bool c[1000] = {0};
    for(register int i = 1; i <= m; ++i)
    {
        if(c[b[i]]) continue;
        c[b[i]]  = true;
        b[i] += a[x];
        DFS(x - 1, max(t, b[i]));
        b[i] -= a[x];
    }
    return;
}

int main()
{
    cin >> n >> m;
    for(register int i = 1; i <= n; ++i)
    {
        cin >> a[i];
    }
    sort(a + 1, a + n + 1);
    DFS(n, 0);
    cout << ans;
    return 0;
} 
参考程序
原文地址:https://www.cnblogs.com/kcn999/p/10988552.html