码迷,mamicode.com
首页 > 其他好文 > 详细

7.5 深搜-最佳调度问题(枚举排列+回溯+剪枝)

时间:2019-07-06 00:24:00      阅读:104      评论:0      收藏:0      [点我收藏+]

标签:运行   EDA   i++   range   机器   搜索   算法   main   问题   

这几天偷了几天懒,今天为大家讲解一篇深搜好题,典型的全排列问题需运用剪枝+回溯来优化运行时间,与上一道都是比较典型的深搜优化问题。

题目描述

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

输入

第一行有2个正整数n和k,第二行有n个正整数,表示ti

n<7000,c<maxlongin

 

输出

一个整数,输出最早时间

样例输入

7 3
2 14 4 16 6 5 3

 

样例输出

17

题解代码:
#include<iostream>
#include<string>
#include<algorithm>
using namespace std;
int n,k;
int a[7001],ans=0xffffff,s[7001];
bool cmp(int x,int y){
 return x>y;
}
void dfs(int x,int y){//x为当前第i个任务,y为用时最大值
 if(ans<=y) return ;//剪枝
 if(x==n){
  if(y<ans){
   ans=y;
   
  }
  return ;
 }
 for(int i=0;i<k;i++){
  if(s[i]+a[x]<ans){ //最优化剪枝:往容器里放的时候不能超过当前已知的最小值
   s[i]+=a[x];
   dfs(x+1,max(y,s[i]));//搜索下一层,第二个关键字是当前k个容器里的最大值
   s[i]-=a[x];
  }
 }
}
int main(){
// freopen("best_arrange.in","r",stdin);
 scanf("%d%d",&n,&k);
 for(int i=0;i<n;i++){
  scanf("%d",&a[i]);
 }
 sort(a,a+n,cmp);//先对大的任务进行排列比较省时
 dfs(0,0);
 printf("%d\n",ans);
 return 0;
}

题解:n件任务对应k台机器来执行,即枚举k台机器来承载n项任务,对应的dfs(x,y)(x为第x台机器,y为k台机器中的最大值);
1.当n件任务执行完如果y<ans,则ans=y并返回
2.枚举到当前值如果y>=ans,直接返回
3.枚举k台机器的时候,如果第i台机器s[i]+a[x]>=ans,直接continue进入下一次循环,为的是防止出现各台机器之间出现执行任务的相同情况,节省运行时间

7.5 深搜-最佳调度问题(枚举排列+回溯+剪枝)

标签:运行   EDA   i++   range   机器   搜索   算法   main   问题   

原文地址:https://www.cnblogs.com/cxs070998/p/11141198.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!