批处理作业调度(回溯)

来源:互联网 发布:阿里云的域名如何解析 编辑:程序博客网 时间:2024/05/16 08:10

算法设计例题:批处理作业调度(回溯)

memory limit: 5000KB    time limit: 2000MS

accept: 13    submit: 33

Description

给定n个作业的集合 J = { J1,J2,…,J}。每一个作业Ji都有两项任务分别在两台机器上完成。每个作业必须先由机器1处理,然后由机器2处理。作业Ji需要机器j的处理时间为tji,其实i=1,2,…,n,j=1,2。对于一个确定的作业调度,设Fji是作业i在机器j上完成处理的时间。所有作业在机器2上完成处理的时间和称为该作业调度的完成时间和。

 

批处理作业调度问题要求对于给定的n个作业,制定最佳作业调度方案,使其完成时间和达到最小。

Input

输入的第一个为测试样例的个数T( T < 120 ),接下来有T个测试样例。每个测试样例的第一行是作业个数n( n ≤ 7 ),接下来n行,每行两个整数 t1i 和 t2i ,分别表示当前作业在机器1和机器2上的处理时间。( 0 ≤ t1i , t2i ≤ 100 )

Output

对应每个测试样例输出两行,第一行格式为"Case #: M",其中'#'表示第几个测试样例(从1开始计),M为最佳作业调度的时间和。第二行为n个以空格分隔的整数,表示最佳作业调度方案中各作业执行顺序的序号。

Sample Input

1
3
2 1
3 1
2 3

Sample Output

Case 1: 18
1 3 2


源代码:

#include<cstdio>
#include<cstring>
class FlowShop
{
public:
   int n,          //作业数
f1,         //机器1完成处理时间
f,          //完成时间和
bestf,      //当前最优值
       m[35][3],   //各作业所需处理时间
x[35],      //当前作业调度
bestx[35],  //当前最优作业调度
f2[35];     //机器2完成处理时间
 
   void swap(int &a,int &b)
   {
       int c=a;
       a=b;
       b=c;
   }
 
   int play()
   {
       f1=0;f=0;
       bestf=0x3f3f3f3f;
   int i;
       for(i=0;i<=n;++i)
           x[i]=i,f2[i]=0;
       backtrack(1);
       return bestf;
   }
 
   void backtrack(int i)
   {
       if(i>n)
       {
           for(int j=1;j<=n;++j)
               bestx[j]=x[j];
           bestf=f;
       }
       else
       {
           for(int j=i;j<=n;++j)
           {
               f1+=m[x[j]][1];
               f2[i]=((f2[i-1]>f1)?f2[i-1]:f1)+m[x[j]][2];
               f+=f2[i];
               if(f<bestf)
               {
                   swap(x[i],x[j]);
                   backtrack(i+1);
                   swap(x[i],x[j]);
               }
               f1-=m[x[j]][1];
               f-=f2[i];
           }
       }
   }
};
 
int main()
{
 
int T,cas=1;  
scanf("%d",&T);
   while(T--)
   {
       FlowShop p;
       scanf("%d",&p.n);
       int i;
       for(i=1;i<=p.n;++i)
           scanf("%d %d",&p.m[i][1],&p.m[i][2]);
       printf("Case %d: %d\n",cas++,p.play());
       for(i=1;i<=p.n;++i)
       {
           if(i!=1) putchar(' ');
           printf("%d",p.bestx[i]);
       }
       puts("");
   }
   return 0;
}



原创粉丝点击