题目叙述
假设有n个任务由k个可并行工作的机器完成。完成任务i需要的时间为ti。试设计一个算法找出完成这n个任务的最佳调度,使得完成全部任务的时间最早。
对任意给定的整数n和k,以及完成任务i需要的时间为ti,i=1,2,…,n。设计一个优先队列式分支限界法,计算完成这n个任务的最佳调度。
给出输入数据。第1行有2个正整数n和k。第2行的n个正整数是完成n个任务需要的时间。
样例输入
7 3
2 14 4 16 6 5 3
样例输出
17
思路
(仅做参考)
由于题目一定要用优先队列碾过去,中间卡了一下(可能就fw才会卡吧)然后没找到类似的(可能是我太废了,搜索引擎都不会 QAQ),所以来整理一下:
以下例子以样例做参考
1、首先我们先假象3个time值,如下,这3个time值分别代表三个机器的工作时间。
2、然后我们知道所有的事件都必须完成,所以一个事件只有3种状态,在机器1中、在机器2中以及在机器3中。
3、所以我们分别对这三种情况进行判断,判断是否入列。
先给出我对node吧(相关作用都在注释里了)
struct node //定义一个node
{
int time[M]; //当前的time
int num; //当前的位置
int tt; //当前的最大值
bool operator<(const node& a)const{
return tt > a.tt;
}
}point; //当前点
基于以上的基础,就可以写出核心代码了吧
for (int i = 1; i <= k; i++){
node next; //定义中间变量并赋值
next.num = point.num + 1;
for (int m = 1; m<= k; m++){
next.time[m] = point.time[m];
}
next.time[i] += x[next.num];
next.tt = max(next.time[i], point.tt);
if (next.tt < best){ //剪枝
q.push(next);
}
}
里面其实就分成两个部分,上半部分是赋值,下半部分是剪枝,不断把符合条件的值往优先队列里整,并且通过循环,不断优化结果。
源代码
如果有错误,欢迎大佬们指正
//author:炸鸡柳
#include <iostream>
#include <queue>
#include <algorithm>
using namespace std;
const int M = 100;
const int INF = 0x3f3f3f3f;
int x[M], n, k;
int best = INF; //最佳值
struct node //定义一个node
{
int time[M]; //当前的time
int num; //当前的位置
int tt; //当前的最大值
bool operator<(const node& a)const{ //重载运算符,实现优先队列从小到大排列
return tt > a.tt;
}
}point; //当前点
int p_queue(){
priority_queue<node> q;
for (int i = 1; i <= k; i++){ //初始化
point.time[i] = 0;
}
point.num = 0;
point.tt = 0;
while (point.tt < best){ //不符合退出循环
if(point.num == n){
best = point.tt; //达到最后一点给best赋值
}else{
for (int i = 1; i <= k; i++){
node next; //定义中间变量并赋值
next.num = point.num + 1;
for (int m = 1; m<= k; m++){
next.time[m] = point.time[m];
}
next.time[i] += x[next.num];
next.tt = max(next.time[i], point.tt);
if (next.tt < best){ //剪枝
q.push(next);
}
}
}
if(q.empty()){ //队列无值退出循环
return best;
}else{ //取队列中第一个值进入下一步循环
point = q.top();
q.pop();
}
}
return best;
}
int main(){
cin >> n >> k; //输入
for (int i = 1; i <= n; i++){
cin >> x[i];
}
cout << p_queue() << endl; //输出
}
结果
如果有错误,欢迎大佬们指正,蒟蒻在此谢过了