加工生產排程
心路歷程(如果你沒有時間請直接跳到下一板塊(。・_・)/~~~)
針對於這道題,一開始博主並不知道也沒有用所謂的Johnson演算法;
① 當博主發現這是一道貪心演算法的時候,也沒有很直接的思路和策略,所以博主就用了最直接的a車間的工作時間除以b車間的工作時間 (水過了44分的資料)
bool mycmp(number x,number y) { return x.c<y.c; } for(int i=1;i<=n;i++) { num[i].b=read(); num[i].c=(num[i].a*1.0)/(num[i].b*1.0);//這個就是博主的鬼畜求商 } sort(num+1,num+n+1,mycmp); //這些是部分程式碼
//下面是模擬求和
ans+=num[1].a;
for(int i=1;i<n;i++)
{
ans+=num[i].b;
int tot=num[i+1].a-num[i].b;
ans+=tot;
}
ans+=num[n].b;
printf("%lld\n",ans);
② 當博主發現並不能解決這道題的時候,又思考了好長時間(或許是博主太弱了),博主發現實際上a車間的工作是連續不停的!!於是乎,博主就
想到了用a車間的總時間加上b車間的最小值,因為在a車間完成之後,b車間應該是會有剩餘一件的物品,此時若使b車間最後加工的一件物品的工作時間最小,那麼不就是總時間最小了嗎!!!!!!
for(int i=1;i<=n;i++) { num[i].id=i; num[i].a=read(); sum1+=num[i].a;//sum1和sum2在這裡分別是a車間的工作總和和b車間的工作總和 a1=min(a1,num[i].a);//a1,b1分別是a車間的最小的工作時間和b車間的最小工作時間 } for(int i=1;i<=n;i++) { num[i].b=read(); num[i].c=(num[i].a*1.0)/(num[i].b*1.0);//依舊是上面的鬼畜演算法 b1=min(b1,num[i].b); sum2+=num[i].b; } sort(num+1,num+1+n,mycmp); if(sum1>sum2) { ans+=sum1; ans+=b1; } else { ans+=sum2; ans+=a1; } printf("%lld\n",ans);
現在博主想到自己之前的種種做法發現這其中都是有問題的
1.首先先說貪心策略(就是內個鬼畜演算法的排列方式)是博主靈光一現 瞎謅出來的,缺乏證明(但是不得不說是可以水 分的 );
2.模擬的時候就是根本沒有一個依據啥的就是在瞎搞;
這是正文!
針對於A,B車間,A車間是一直在運作,而B車間中間是有空缺的,因為有時候,B車間會因為等待A車間的第一次生產而需要更多的時間。
那麼這個時候,就可以想一下,應該如何排序的呢?使得B車間中的空閒時間最少。
可以自己稍微思考一下,如果不會就看一下下面的正確策略。
①策略:讓在A車間中花費時間最少的在前面(這樣子的話,就會讓B最先開始開工,那麼一開始等待的時間就會較少一些),讓在B車間中工作時間最少的放在最後(那麼就是在A車間工作結束後,B車間工作的時間最少),這樣的話就會很好的處理到了A,B車間的空閒時間最少,從而得到了最少的工作時間。
部分處理程式碼如下
struct number
{
int id,a,b,m;
};
number num1[1010];//這裡面儲存的是原始的排列順序
number num2[1010];//這裡面儲存的是排列後的順序
for(int i=1;i<=n;i++)
{
num1[i].b=read();
num1[i].m=min(num1[i].a,num1[i].b);//先找到第i件中的A,B車間的最小的
}
sort(num1+1,num1+1+n,mycmp);
int l=0,r=n+1;
for(int i=1;i<=n;i++)
{
if(num1[i].m==num1[i].a)//此時最小值是A車間中的,應該放在佇列的前面
num2[++l]=num1[i];
else
num2[--r]=num1[i];//同理可得此時最小值是B車間中的,應該放在佇列的後面
}
②模擬求和
我覺得對於我來說,上面的排序並不是很大的問題,而真正的難題是最後收尾的求和
在這裡以B車間為標準,(即若是求出來了B車間中的工作時間,那麼就是這個過程中的工作時間)
見下圖(針對於樣例來說):
所以可以整體考慮,當A車間的整體的值大於B車間的值是,B車間的工作時間就要變成A車間的工作時間。
見部分程式碼:
for(int i=1;i<=n;i++)
{
sum1+=num2[i].a;
sum2=max(sum1,sum2)+num2[i].b;
}
見全部程式碼如下:
#include<bits/stdc++.h>
using namespace std;
int n;
long long sum1=0,sum2=0;
struct number
{
int id,a,b,m;
};
number num1[1010];
number num2[1010];
inline int read()
{
int x=0,f=1;char ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-') f=-1;ch=getchar();}
while(ch>='0'&&ch<='9'){x=x*10+ch-'0'; ch=getchar();}
return x*f;
}
bool mycmp(number x,number y)
{
return x.m<y.m;
}
int main()
{
//freopen("1.in","r",stdin);
n=read();
for(int i=1;i<=n;i++)
{
num1[i].id=i;
num1[i].a=read();
}
for(int i=1;i<=n;i++)
{
num1[i].b=read();
num1[i].m=min(num1[i].a,num1[i].b);
}
sort(num1+1,num1+1+n,mycmp);
int l=0,r=n+1;
for(int i=1;i<=n;i++)
{
if(num1[i].m==num1[i].a)//此時應該放在佇列的前面
num2[++l]=num1[i];
else
num2[--r]=num1[i];
}
for(int i=1;i<=n;i++)
{
sum1+=num2[i].a;
sum2=max(sum1,sum2)+num2[i].b;
}
printf("%lld\n",sum2);
for(int i=1;i<=n;i++)
{
printf("%d ",num2[i].id);
}
return 0;
}
其實,上面的心路歷程我也不知道寫了些什麼……
總之,2019肯定會更好的呀!!!!