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; }