编程之美 1.8小飞的电梯调度算法

问题:由于楼层并不高,在繁忙时段,每次电梯从一层往上走时,我们只允许停到其中某一层。所有乘客再从这层去往自己的目的楼层。

电梯停在哪一层,能够保证乘客爬楼梯之和最少?

解法一:

枚举停在第i层的情况,计算当停在第i层时所爬楼梯数为nFloor,取其最小值nMinFloor,时间复杂度O(N^2)

解法二:

有没有方法可以通过已知第i层的nFloor,推算出第i+1层的nFloor呢?

N1为第i层以下的乘客数,N2为第i层的乘客数,N3为第i层以上的乘客数,已知乘客在第i层的nFloor值为Y

如果电梯改停在i-1层时,那么此时nFloor值为Y-N1+(N2+N3)

如果电梯改停在i+1层时,此时nFloor值为Y-N3+(N1+N2)

由此可见N1+N2<N3时,停i+1层更好,这样我们先计算第一层时的N1、N2、N3的值,按照上述规则遍历一次即可得出 nMinFloor 和 nTargetFloor。

这样时间复杂度就降为O(N)。

#include <iostream>
using namespace std;

const int MAXN=2;
int nPerson[MAXN+1]={-1,7,3};        //nPerson[i]表示第i层乘客数
int nFloor,nMinFloor,nTargetFloor;

//O(N^2)
void dispatching1(int N)
{
    nTargetFloor=-1;
    for (int i=1;i<=N;++i)
    {
        nFloor=0;
        int j;
        for(j=1;j<i;++j)
            nFloor+=nPerson[j]* (i-j);//i层以下
        for(j=i+1;j<=N;++j)
            nFloor+=nPerson[j]*(j-i);//i层以上
        if(nTargetFloor == -1 || nMinFloor > nFloor)
        {
            nMinFloor = nFloor;
            nTargetFloor =i;
        }
    }
}
//O(N)
int N1,N2,N3;
void dispatching2(int N)
{
    nTargetFloor=1;
    nMinFloor=0;
    int i;
    for(N1=0,N2=nPerson[1],N3=0,i=2;i<=N;++i)
    {
        N3+= nPerson[i];
        nMinFloor+=nPerson[i]*(i-1);
    }
    for (i=2;i<=N;++i)
    {
        if (N1+N2<N3)
        {
            nTargetFloor=i;
            nMinFloor+=(N1 + N2 -N3);
            N1 +=N2;
            N2 =nPerson[i];
            N3 -=nPerson[i];
        }
        else
            break;
    }

}
void main()
{
    dispatching1(MAXN);
    //dispatching2(MAXN);
    cout<<"TargetFloor:"<<nTargetFloor<<endl;
    cout<<"MinFloor:"<<nMinFloor<<endl;
}
posted @ 2013-10-11 16:47  Linka  阅读(440)  评论(0编辑  收藏  举报