codevs 3008 加工生产调度
时间限制: 1 s
空间限制: 128000 KB
题目等级 : 黄金 Gold
题目描述 Description
某工厂收到了n个产品的订单,这n个产品分别在A、B两个车间加工,并且必须先在A车间加工后才可以到B车间加工。
某个产品i在A、B两车间加工的时间分别为Ai、Bi。怎样安排这n个产品的加工顺序,才能使总的加工时间最短。这里所说的加工时间是指:从开始加工第一个产品到最后所有的产品都已在A、B两车间加工完毕的时间。
输入描述 Input Description
第一行仅—个数据n(0<n<1000),表示产品的数量。
接下来n个数据是表示这n个产品在A车间加工各自所要的时间(都是整数)。
最后的n个数据是表示这n个产品在B车间加工各自所要的时间(都是整数)。
输出描述 Output Description
第一行一个数据,表示最少的加工时间;
样例输入 Sample Input
5
3 5 8 7 10
6 2 1 4 9
样例输出 Sample Output
34
数据范围及提示 Data Size & Hint
0<n<1000
贪心,需要用到Johnson算法,
不过在网上见大佬用了一种奇妙的思路,居然A了,不可思议
思路是:
先求出A厂的总时间suma,B厂的总时间sumb。
若suma>sumb,则总时间 ans=suma+minb(B厂时间的最小值)。
反之,总时间 ans=sumb+mina。
1 #include<cstdio> 2 #include<algorithm> 3 using namespace std; 4 int n,m,ans,mina=99999999,minb=99999999,suma,sumb; 5 int main() 6 { 7 scanf("%d",&n); 8 for(int i=1;i<=n;++i) 9 { 10 scanf("%d",&m); 11 mina = min(mina,m); 12 suma += m; 13 } 14 for(int i=1;i<=n;++i) 15 { 16 scanf("%d",&m); 17 minb = min(minb,m); 18 sumb += m; 19 } 20 if(suma>sumb) ans = suma + minb; 21 else ans = sumb + mina; 22 printf("%d",ans); 23 return 0; 24 }
Johnson做法是
1 #include<cstdio> 2 #include<algorithm> 3 4 using namespace std; 5 const int N = 1010; 6 struct Job{ 7 int tme,id,medchin; 8 }s[N]; 9 int n,m,ans; 10 int a[N],b[N],c[N],t[N]; 11 12 bool cmp(Job a,Job b) 13 { 14 return a.tme < b.tme; 15 } 16 void jonson() 17 { 18 for(int i=1;i<=n;++i) 19 { 20 if(a[i]<b[i]) s[i].tme = a[i],s[i].medchin = 1; 21 else s[i].tme = b[i],s[i].medchin = 2; 22 s[i].id = i; 23 } 24 sort(s+1,s+n+1,cmp); 25 int l = 0; 26 int r = n+1; 27 for(int i=1;i<=n;++i) 28 { 29 if(s[i].medchin == 1) 30 c[++l] = s[i].id; 31 else if(s[i].medchin = 2) 32 c[--r] = s[i].id; 33 } 34 } 35 int main() 36 { 37 scanf("%d",&n); 38 for(int i=1;i<=n;++i) 39 scanf("%d",&a[i]); 40 for(int i=1;i<=n;++i) 41 scanf("%d",&b[i]); 42 jonson(); 43 for(int i=1;i<=n;i++)//计算最少时间 44 t[i]=t[i-1]+a[c[i]]; 45 ans=t[1]+b[c[1]]; 46 for(int i=2;i<=n;i++) 47 ans=max(ans,t[i])+b[c[i]]; 48 printf("%d ",ans); 49 return 0; 50 }
Johnson算法中,c数组表示的是加工顺序
洛谷上也有一道题P1248
与codevs不同的是需要输出加工顺序,应该输出c数组就是了
结果只过了三个点QAQ,求大佬解释
1 #include<cstdio> 2 #include<algorithm> 3 4 using namespace std; 5 const int N = 1010; 6 struct Job{ 7 int tme,id,medchin; 8 }s[N]; 9 int n,m,ans; 10 int a[N],b[N],c[N],t[N]; 11 bool cmp(Job a,Job b) 12 { 13 return a.tme < b.tme; 14 } 15 void jonson() 16 { 17 for(int i=1;i<=n;++i) 18 { 19 if(a[i]<b[i]) s[i].tme = a[i],s[i].medchin = 1; 20 else s[i].tme = b[i],s[i].medchin = 2; 21 s[i].id = i; 22 } 23 sort(s+1,s+n+1,cmp); 24 int l = 0; 25 int r = n+1; 26 for(int i=1;i<=n;++i) 27 { 28 if(s[i].medchin == 1) 29 c[++l] = s[i].id; 30 else if(s[i].medchin = 2) 31 c[--r] = s[i].id; 32 } 33 } 34 int main() 35 { 36 scanf("%d",&n); 37 for(int i=1;i<=n;++i) 38 scanf("%d",&a[i]); 39 for(int i=1;i<=n;++i) 40 scanf("%d",&b[i]); 41 jonson(); 42 for(int i=1;i<=n;i++)//计算最少时间 43 t[i]=t[i-1]+a[c[i]]; 44 ans=t[1]+b[c[1]]; 45 for(int i=2;i<=n;i++) 46 ans=max(ans,t[i])+b[c[i]]; 47 printf("%d ",ans); 48 for(int i=1;i<=n;++i) 49 printf("%d ",c[i]); 50 return 0; 51 }