训练4.06(Saving Endeavour 双机器调度问题Johnson)

今天训练做到一道题,发现居然有个算法:Johnson调度算法,觉得特别神奇!

流水调度问题的Johnson算法:
作业 i 需要走两步:先后进入A、B车间,各花费ai、bi时间,那么:
令N1={ i | ai < bi },N2={ i | ai >= bi };
将N1中作业按照ai的非递减排序,将N2中作业按照bi的非递增排序;
N1中作业和N2中作业相连接构成满足Johnson法则的最优调度。

以上摘自:http://blog.sina.com.cn/s/blog_7c35df9b0100vga3.html

即可理解为:
开始让第二台机器等的时间缩小
最后让第一台机器等的时间更小

好啦做题啦:
题目速递http://poj.org/problem?id=2751

题意:有n项工作,各项工作需要经过车间A、车间B才ok。求如何安排时间最短。

根据上述算法,对工作做好安排后,计算花费时间即可。

(车间A无需等待谁,只需要自己有空就可以开干。而能进入车间B是只有那些已经经过车间A的才可以。)

#include<cstdio>
#include<iostream>
#include<algorithm>
#include<vector>
#include<string>
#include<queue> 
#include<cmath>
#include<cstring>
using namespace std;
#define ll long long
#define pii pair<int,int>
#define pll pair<ll,ll>
const int maxn=1e5+6;
const int inf=0x3f3f3f3f;
struct A{
    int x,y;
}A1[maxn],A2[maxn];
bool cmp1(A a1,A a2){
    if(a1.x==a2.x)
	return a1.y<a2.y;
    return a1.x<a2.x;
}
bool cmp2(A a1,A a2){
    if(a1.y==a2.y)
	return a1.x>a2.x;
    return a1.y>a2.y;
}
int main(){
    int n;
	while((scanf("%d",&n)!=EOF)&&n){
        int cnt1,cnt2;
        cnt1=cnt2=0;
        for(int i=0;i<n;i++){
        	int x,y;
            scanf("%d%d",&x,&y);
            if(x<y){
                A1[cnt1].x=x;
                A1[cnt1].y=y;
                cnt1++;
            }
            else{
                A2[cnt2].x=x;
                A2[cnt2].y=y;
                cnt2++;
            }
        }
        sort(A1,A1+cnt1,cmp1);
        sort(A2,A2+cnt2,cmp2);
        int ans1,ans2;
        ans1=ans2=0;
        for(int i=0;i<cnt1;i++){
             ans1+=A1[i].x;
             if(ans2<ans1)
             ans2=ans1+A1[i].y;
             else
             ans2+=A1[i].y;
        }
        for(int i=0;i<cnt2;i++){
             ans1+=A2[i].x;
             if(ans2<ans1)
             ans2=ans1+A2[i].y;
             else
             ans2+=A2[i].y;
        }
        printf("%d\n",ans2);
    }
}

说真的特别害怕这种问题,脑袋瓜子最受不住这类题目。。。想半天方法都是猜样例各种猜测。。。就怕码半天还猜错OMG

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值