- 问题描述
车间有m(m>0)台机床,可同时加工工件,但同一台机床不能同时加工多个工件。今有n(n>0)个工件,加工不同工件所花费的时间有差异。各工件可以在任何一台机床上加工。同一工件在不同机床上加工,花费的时间相同。一台机床加工完一个工件后可以立刻加工下一个工件,换工件的时间忽略不计。请找出最优分派方案,使得加工完所有工件所花费的时间最短。
- 输入格式
输入的第1行是两个正整数,分别表示m和n的值。第2行有n个正整数,表示加工第i(i=1,2,…,n)个工件需要花费的时间。
- 输出格式
先输出m行,第i(i=1,2,…,m)行用空格分隔若干个整数,表示哪些工件在第i台机床上加工。最后还要输出1个整数,表示加工所有工件需要花费多少时间。
- 数据范围
1≤m≤20,1≤n≤200
第一种,递归,这种方法可算数据的范围较大。
#include<iostream>
#include<algorithm>
using namespace std;
int n,m; //n表示要处理的工件数,m表示机床数
int totalTime[200]={0}; //存各个机器处理工件的总时间
int optimumTime; //记录所需的最佳时间
int WPtime[200]; //存放机器处理各个工件的时间
int WP[200]; //存放各个工件被处理所需的时间
int Machine; //记录要处理工件的机床
class Solution{
public:
void OptimumTimes(int k)
{
if(k>=n)
return ;
//第一种情况:机床比要处理的工件多
if(m>=n)
{
optimumTime=getMaxTime(WP);
for(int i=0;i<n;i++)
{
WPtime[i]=i;
totalTime[i]+=WP[i];
}
return ;
}
//第一遍先让各个机床都开始工作,然后记录处理工件时间最短的机床
if(k==0)
{
for(int i=0;i<m;i++,k++)
{
Machine=i;
WPtime[i]=Machine;
totalTime[i]+=WP[k];
}
optimumTime=WP[k];
}
//开始处理第一遍之后的工件
if(k<n)
{
totalTime[Machine]+=WP[k]; // 把即将要处理的工件的时间加到上一遍记录的最短时间上
WPtime[k]=Machine; //记录哪个机床要处理工件,并记录处理时间
optimumTime=totalTime[Machine]; //记录机床处理当前工件的总时间
for(int i=0;i<m;i++)
{
if(totalTime[i]<=optimumTime) //寻找所有机床中处理工件时间最短的机床
{
optimumTime=totalTime[i];
Machine=i;
}
}
OptimumTimes(k+1);
}
}
int getMaxTime(int t[])
{
int maxTime=t[0];
for(int i=1; i<n; i++)
{
if(maxTime<t[i])
{
maxTime=t[i];
}
}
return maxTime;
}
void show()
{
if(n>m)
{
for(int i=0;i<m;i++)
{
for(int j=0;j<n;j++)
{
if(WPtime[j]==i)
cout<<WP[j]<<" ";
}
cout<<endl;
}
}
else
{
for(int i=0;i<n;i++)
cout<<WP[i]<<endl;
}
cout<<getMaxTime(totalTime);
}
};
int main()
{
cin>>m>>n;
for(int i=0;i<n;i++)
cin>>WP[i];
sort(WP,WP+n, greater<int>()); //降序排序
Solution s;
s.OptimumTimes(0);
cout<<endl;
s.show();
return 0;
}
第二种,回溯算法,这种算法可算数据的范围较小。
#include<iostream>
#include<algorithm>
using namespace std;
int n,m;
int WP[200],totalTime[200],optimumTime=1e8;
int allocate[200];
class Solution
{
public:
void Back(int k,int maxnum)
{
if(maxnum>=optimumTime)
return;
if(k>=n)
{
if(maxnum<optimumTime)
optimumTime=maxnum;
return;
}
for(int i=0;i<m;i++){
if(totalTime[i]+WP[k]<=optimumTime){
totalTime[i]+=WP[k];
allocate[k]=i;
Back(k+1,max(maxnum,totalTime[i]));
totalTime[i]-=WP[k];
}
}
return;
}
void show(int t[])
{
for(int i=0;i<m;i++)
{
for(int j=0;j<n;j++)
{
if(allocate[j]==i)
cout<<WP[j]<<" ";
}
cout<<endl;
}
cout<<optimumTime<<endl;
}
};
int main(){
cin>>m>>n;
for(int i=0;i<n;i++)
cin>>WP[i];
sort(WP,WP+n,greater<int>());//排序
Solution s;
cout<<endl;
s.Back(0,0);
s.show(allocate);
return 0;
}