电梯调度算法(微软面试题)

文章出处:飞诺网(http://www.diybl.com/course/3_program/c++/cppjs/20090221/156116.html)

 

在高峰时间,实习生小飞常常会被电梯每层楼都停弄得很不耐烦,于是他想出了这样一个办法:由于楼层并不高,那么在繁忙的时间,每次电梯从一层往上走时,我们只允许电梯停在其中的某一层。所有乘客都从一楼上电梯,到达某层楼后,电梯听下来,所有乘客再从这里爬楼梯到自己的目的层。在一楼时,每个乘客选择自己的目的层,电梯则自动计算出应停的楼层。  问:电梯停在哪一层楼,能够保证这次乘坐电梯的所有乘客爬楼梯的层数之和最少

 

解法一:采用枚举的方法 O(N^2)

#include<vector>
#include<iostream>
using namespace std;
int main(void)
{
int i,j,n,person,temp,ans,layer;
vector<int> num;
while(cin>>n)  //表示n层数
{
for(i=1;i<=n;i++)
{
cin>>person;    //表示第几层下电梯的人数
num.push_back(person);
}
ans=-1;
for(i=1;i<=n;i++)
{
temp=0;
for(j=1;j<=n;j++)
{
if(i>=j)
temp+=num[j-1]*(i-j);
else
temp+=num[j-1]*(j-i);
}
if(ans==-1||temp<ans)
{
ans=temp;
layer=i;
}
}
cout<<"最少的层数: "<<ans<<endl;
cout<<"在第 "<<layer<<" 层下"<<endl;
}
return 0;
}

 

解法二:

线性算法 O(n)
1:首先通过一次扫描计算第一层下所有乘客爬电梯的层数总和
2:然后通过每一层动态变化求得最后的结果
   比如现在在第i层所有乘客爬电梯的层数总和为temp
   在第i层下的有num1  在第i层的有num2  在第i层上的有num3
   则如果在第i-1层下   temp+num3-num1-num2
     如果在第i+1层下   temp+num1+num2-num3
#include<vector>
#include<iostream>
using namespace std;
int main(void)
{
int num1,num2,num3,i,n,ans,person,layer;
vector<int> num;
while(cin>>n)
{
vector<int> sum(n+2);
sum[0]=0;
ans=0;
num.push_back(0);
for(i=1;i<=n;i++)
{
cin>>person;    //表示第几层下电梯的人数
num.push_back(person);
sum[i]=sum[i-1]+num[i];
ans+=num[i]*(i-1);
}
//cout<<"ans="<<ans<<endl;
layer=1;
for(i=2;i<=n;i++)
{
num2=num[i-1];
num1=sum[i-1]-num2;
num3=sum[n]-sum[i-1];
if(num1+num2<num3)
{
ans=ans+num1+num2-num3;
layer=i;
}
}
cout<<"最少的层数: "<<ans<<endl;
cout<<"在第 "<<layer<<" 层下"<<endl;
}
}

 

解法二的改进:
#include<vector>
#include<iostream>
using namespace std;
int main(void)
{
int num1,num2,num3,i,n,ans,person,layer;
vector<int> num;
while(cin>>n)
{
ans=0;
num.push_back(0);
num3=0;
for(i=1;i<=n;i++)
{
cin>>person;    //表示第几层下电梯的人数
num.push_back(person);
ans+=num[i]*(i-1);
num3+=num[i];
}
//初始化
num2=num[1];
num3-=num2;
num1=0;
layer=1;
for(i=2;i<=n;i++)
{
if(num1+num2<num3)
{
ans=ans+num1+num2-num3;
layer=i;
num1+=num2;
num2=num[i];
num3-=num[i];
//动态变化,编程技巧
}
else
break;
//这里利用一个性质,最优的层数一定在中间,在他下面和上面的都比他要多
}
cout<<"最少的层数: "<<ans<<endl;
cout<<"在第 "<<layer<<" 层下"<<endl;
}
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值