//问题分析:
// 1.作业合集N={1,2,3…n},//S属于N;M1上不停止的工作,
// 因此M1加工S中的作业时,M2还在加工N-S中的某作业,
// 需要等时间t后才能利用M2.
// 2.这种情况下,完成S作业的最短时间记为T( S,t);//t为安排{N-S}后面的等待时间
// 流水作业调度问题的最优值为T(N,0);//M2无需等待的情况
// 3.对于n个作业,其最优调度为Π,时间为aΠ(1)+T’;
// T’为M2的等待时间为bΠ(1)时,作业aΠ(2,。。。。n)的最优时间
//则T’=T(n-Π(1),bΠ(1));
//可以理解为T是大问题安排的时间,T‘是小问题安排的时间;
//4.最优子结构问题:T(N,o)=min{ai+T(N-i,bi)};------子结构问题,对于N个问题中的每个问题进行调度,
// 将问题规模缩小,求最短的结果作为选择方案
//
//T(S,t)=min{ai+T(S-i,bi+max{t-ai,0})};-------在M2上的等待时间为bi+{t(M2上{N-S}后面的等待时间)-ai(M1上的工作时间)}
//(冲抵了,t是从ai开始工作,M2所等待的时间)
//如果t>ai,那么安排a1后,安排别的工作M2等待的时间就为t-ai,;
//如果t<=ai,那么,安排a1后,安排别的工作M2等待的时间就为0;
图片来源:https://www.cnblogs.com/f91og/p/6024706.html
#include <iostream>
#include<string>
#include<algorithm>
using namespace std;
#define N 6
struct node {
int time;//执行时间
int index;//作业序号
bool group;//机器1、2
};
bool cmp(node a, node b)//升序
{
return a.time < b.time;//a小则true
}
int main()
{
int a[N] = { 2,7,6,4,6,8 }, b[N] = {5,3,2,7,9,2};
node *c=new node [N];
int best[N];//最优调度顺序
for (int i = 0; i < N; i++)
{
c[i].index = i;
c[i].time = a[i] > b[i] ? b[i] : a[i];//赋值小的
c[i].group = a[i] <= b[i];//作业i在M1上时间小则true
}
//排序
sort(c, c + N, cmp);//c[]作业时间升序
int j = 0, k = N - 1;
//a小前,b小后面
for (int i = 0; i < N; i++)
{
if (c[i].group) {
//a[i]小
best[j++] = c[i].index;
}
else {
best[k--] = c[i].index;//b[i]大的放在后面
}
}
//
j = a[best[0]];//第一个作业在M1上的时间
k = j + b[best[0]];//第一个作业在M2上的时间+M1上的时间
for (int i = 1; i < N; i++)
{
j += a[best[i]];//按最优调度的顺序下a[]累计时间总和
k = j<k?(k+b[best[i]]):j+b[best[i]];//
//1.best[1..+..i]<a[best0]+b[best0];k=a[best0]+b[best0]+b[best1....];
//2 . >= ;k=a{best0...i]+b[besti+1...];
}
cout << k<<endl;//消耗时间最大值
for (int i = 0; i < N; i++)//序号输出
{
cout << best[i] + 1 << ' ';
}
cout << endl;
return 0;
}
代码思路来源,非常详细!!!!!!
https://blog.csdn.net/qq_44766883/article/details/106211941