最佳调度问题(搜索回溯)
最佳调度问题
【问题描述】
假设有n个任务由k个可并行工作的机器完成。完成任务i需要的时间为ti。试设计一个算法找出完成这n个任务的最佳调度,使得完成全部任务的时间最早。
【编程任务】
对任意给定的整数n和k,以及完成任务i需要的时间为ti,i=1~n。编程计算完成这n个任务的最佳调度。
【输入格式】
由文件machine.in给出输入数据。第一行有2 个正整数n和k。第2 行的n个正整数是完成n个任务需要的时间。
【输出格式】
将计算出的完成全部任务的最早时间输出到文件machine.out。
【输入样例】
7 3
2 14 4 16 6 5 3
【输出样例】
17
/*搜索问题我会先想每个小问题面临的共同条件是什么,每加入一件任务,他加入的条件是什么?他要加入哪个机器?加入的条件是什么?时间怎样最短?然后我就蒙圈了、、、我智障的想法是search(1,1)把第一个加入第一个机器,然后直到search(7,1)把第七个加入第一个,然后再加一个机器search(1,2)直到search(7,2)后来想想真是愚蠢呐,上网搜了一下、、
才明白...orz,search(int,int)里面的两个参数一个表示加入的第几个任务,另一个是现在的时间,所以search()里面是什么很重要,我发现这就比如前面的题目的效率问题,求最高的效率,search()里面也有一个参数代表效率,从0开始;还有着一个题注意剪枝,当这一种情况已经比之前找到的最小值大时这种情况就可以舍弃不用考虑了QWQ*/
#include<iostream> #include<cstdio> #include<cstdlib> using namespace std; int a[30],s[30]; int n,k,minn=0x7ffff; void search(int,int); int main() { scanf("%d%d",&n,&k); for(int i=1; i<=n; i++) //输入每个时间 scanf("%d",&a[i]); search(1,0);//加入第一个时间,现在花费的时间是0; cout<<minn; return 0; } void search(int x,int y) { if(y>=minn)return;//剪枝 已经比最小的大了就不用再放了,舍弃这种方法 if(x>n) { //放完了进行判断 if(y<minn)minn=y; return; } for(int i=1; i<=k; i++) { if(s[i]+a[x]<=minn) { //剪枝 s[i]+=a[x]; search(x+1,max(y,s[i])); s[i]-=a[x];//回溯 } } return; }