某汽⻋公司在有多条装配线的⼯⼚内⽣产汽⻋,⼀个汽⻋底盘在进⼊每⼀条装配线后,在每个⼯作站会在汽⻋底盘上安装不同的部件,最后完成的汽⻋从装配线的末端离开。
每⼀条装配线上都有 n 个⼯作站,装配线i的第 j 个⼯作站 用S(i,j)表示, 在两条装配线相同位置的⼯作站执⾏相同的功能,但由于⼯作站是在不同的时间建造的,并且采⽤了不同的技术,因此,每个⼯作站上完成装配所需要的时间也不相同。
正常情况下,底盘从同⼀条装配线的上⼀个⼯作站移到下⼀个⼯作站所花费的时间可以忽略,但是遇到紧急订单时也会将未完成的底盘从⼀条装配线的⼀个⼯作站移到另⼀条装配线的下⼀个⼯作站,但从某装配线移⾛到另一个装配线的下一工作站也需要花费一定时间,此外,底盘进⼊装配线 i 需要的时间为 e(i),离开装配线 i 需要的时间是 x(i)。
请选择在哪些装配线内的⼯作站进行装配,以使汽⻋通过⼯⼚的总时间最⼩。
如下图所示, 最快的时间是选择装配线1的 1、3和 6 号⼯作站以及装配线 2 的 2、4 和 5 号⼯作站,最短的通过时间为38。
输入格式:
第一行是装配线数量LINES和工作站数量STATIONS,用空格符间隔。
接下来LINES行是每个装配线上工作站的装配时间。
接下来LINES行是从当前装配线移到其它装配线下一个工作站的移动时间。注意最后一个工作站没有移动时间。
接下来一行是进入各条装配线的时间e[i]。
接下一行是退出各装配线的时间x[i]。
输出格式:
第一行输出总的装配时间。
接下来按照顺序输出装配过程,格式如下:
装配线 工作站
输入样例:
在这里给出一组输入。例如:
2 6
7 9 3 4 8 4
8 5 6 4 5 7
2 3 1 3 4
2 1 2 2 1
2 4
3 2
输出样例:
在这里给出相应的输出。例如:
Total Time 38
1 1
2 2
1 3
2 4
2 5
1 6
#include<bits/stdc++.h>
using namespace std;
#define int long long
#define PII pair<int,int>
#define IOS ios_base::sync_with_stdio(0);
int n,m,k;
int e[10086];//从每个流水线离开耗时
int in[10086];//进入流水线耗时
int zp[1005][1005];//存储流水线各个工作站的耗时
int zy[1005][1005];//存储流水线到其他流水线的时间
vector<PII>ans;
int mn=0x3f3f3f3f;
vector<PII>ve;
void dfs(int x,int y,int z){
if(y==m){//退出条件
if(mn>z+e[x]){
mn=z+e[x];
ans=ve;
}
return ;
}
for(int i=1;i<=n;i++){
if(y==0){//如果是初次进入,先加上入车间的时间
ve.push_back({i,y+1});
dfs(i,y+1,z+in[i]+zp[i][y+1]);
ve.pop_back();
}else{
if(x!=i&&(i-x==1||(i==1&&x==n))){//如果不是同一条路并且是下一条路,本题恶心点,条件没给全,只能从1-2,2-3走,走到尽头才能回头到1号线
ve.push_back({i,y+1});
dfs(i,y+1,z+zp[i][y+1]+zy[x][y]);
ve.pop_back();
}
if(x==i){
ve.push_back({i,y+1});
dfs(i,y+1,z+zp[i][y+1]);
ve.pop_back();
}
}
}
}
signed main(){
cin >> n >> m;
memset(e,0,sizeof(e));
memset(in,0,sizeof(in));
int a;
for(int i=1;i<=n;i++){
for(int j=1;j<=m;j++){
cin >> zp[i][j];
}
}
for(int i=1;i<=n;i++){
for(int j=1;j<m;j++){
cin >> zy[i][j];
}
}
for(int i=1;i<=n;i++){
cin >> in[i];
}
for(int i=1;i<=n;i++){
cin >> e[i];
}
dfs(0,0,0);
cout << "Total Time " << mn << endl;
for(int i=0;i<ans.size();i++){
cout << ans[i].first << " " << ans[i].second << endl;
}
return 0;
}