【9506】最佳调度问题

Time Limit: 1000ms second
Memory Limit: 32m 问题描述:
假设有n个任务由k个可并行工作的机器完成。完成任务i需要的时间为ti。对任意给定的整数n和k,以及完成任务i需要的时间ti,i=1~n,试设计一个算法找出完成这n个任务的最佳调度,使得完成全部任务的时间最早

Input

第一行有2个正整数n和k。第二行的n个正整数是完成n个任务需要的时间。

Output

计算出的完成全部任务的最早时间

Sample Input

7 3
2 14 4 16 6 5 3

Sample Output

17

【题解】

这题和排队打水那题不一样,不能用贪心法来做。同时,这道题的数据也显示,某台机器分配一件工作之后,就必须要把这件工作做完才能换其他工作,不能中途更换。这样的话,我们只有为每一个工作分配一台机器就好。然后他会按顺序一直做完。每台机器上用的时间也就可以知道了。最后看一下哪台机器用的时间最长,那就是这种分配工作的方法所用的时间,枚举一下分配的方法就好,最后获取最小值。

【代码】

#include <cstdio>

int n,k,a[20],b[20],min_t = 2100000000;

void input_data()
{
    scanf("%d %d",&n,&k);
    for (int i = 1; i <= n;i++)
        scanf("%d",&a[i]);
    for (int i = 1;i <= k;i++) //一开始所有的机器都没有花费时间
        b[i] = 0;
}

void sear_ch(int x) //为第x件工作分配机器
{
    if (x == n+1) //如果工作全都分配完了
        {
            int max_t = b[1]; //找到所有机器中花费时间最长的机器,即为这次分配所用的时间
            for (int i = 2;i <= k;i++)
                if (b[i] > max_t)
                    max_t = b[i];
            if (max_t < min_t) //如果能够更新最小值 就更新
                min_t = max_t;
            return; //退出这一层递归
        }
    for (int i = 1;i <= k;i++) //枚举k台机器
        {
            if (b[i] + a[x] > min_t) continue;//如果这台机器再加上这件任务会比当前的最小值大就没有必要加了,因为最后会没有办法更新最小值了
            b[i] += a[x]; //第i台机器分配第x件任务
            sear_ch(x+1); //继续分配下一件任务
            b[i] -= a[x]; //回溯
        }
}

void get_ans()
{
    sear_ch(1);
}

void output_ans()
{
    printf("%d
",min_t);
}

int main()
{
    //freopen("F:\rush.txt","r",stdin);
    input_data();
    get_ans();
    output_ans();
    return 0;
}


 

原文地址:https://www.cnblogs.com/AWCXV/p/7632437.html