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

题目:

  亚洲微软研究院所在的希格玛大厦一共有6部电梯。在高峰时间,每层都有人上下,电梯每层都停。实习生小飞常常会被每层都停的电梯弄的很不耐烦,于是他提出了这样一个办法:
  由于楼层并不算太高,那么在繁忙的上下班时间,每次电梯从一层往上走时,我们只允许电梯停在其中的某一层。所有乘客从一楼上电梯,到达某层后,电梯停下来,所有乘客再从这里爬楼梯到自己的目的层。在一楼的时候,每个乘客选择自己的目的层,电梯则计算出应停的楼层。

问:电梯停在哪一层楼,能够保证这次乘坐电梯的所有乘客爬楼梯的层数之和最少?

方法一:暴力枚举,时间复杂度O(N^2)

用数组nPerson[i]存放在第i层下楼的人数,在不同的i层停靠,求所有人需要走的楼层总和,找出总和最小的楼层Target,输出。用两重循环完成计算。

 1 /*
 2 * 1.8.1
 3 *
 4 *  Created on: Jan 9, 2016
 5 *      Author: SeekHit
 6 */
 7 #include "iostream"
 8 #define N 100
 9
10 using namespace std;
11
12 int func(int n, int nPerson[]){
13
14     int nFloor, nMinFloor=0, TargetFloor=0;
15
16     for (int i = 1; i <= n; i++){
17         nFloor = 0;
18         for (int j = 1; j<i; j++)
19             nFloor += (i - j)*nPerson[j];
20         for (int j = i + 1; j <= n; j++)
21             nFloor += (j - i)*nPerson[j];
22
23         if (TargetFloor==0||nMinFloor>nFloor){    //如果没有TargetFloor==0,nMinFloor>nFloor始终无法满足,不执行if里面的内容
24             nMinFloor = nFloor;
25             TargetFloor = i;
26
27         }
28     }
29     return TargetFloor;
30 }
31
32 int main(){
33     int n, Target;
34     int nPerson[N];
35     cout<<"输入楼层总数n:"<<endl;
36     cin>>n;
37     cout<<"输入每层楼下的人数"<<endl;
38     for (int i = 1; i <= n; i++){
39         cout<<"第"<<i<<"层下的人数:"<<endl;
40         cin>>nPerson[i];
41     }
42
43     Target = func(n, nPerson);
44     cout<<"电梯停靠最优层数为:"<<Target<<endl;
45 }

方法二:时间复杂度为O(N)的动态规划的算法

降低时间复杂度,求解。假设停在i层,可以计算出所有乘客需要爬的楼层总数Y。设N1个人在i层以下下楼,N2个人在i层下楼,N3个人在i层以上下楼。

如果现在电梯改在i-1层停靠,现在所有i层和i层以上的都要多走一楼,相当于,总共多爬了N2+N3层,而i层以下的所有人少爬了一楼,就是少了N1层。总数变成了N2+N3-N1层,如果N2+N3-N1<Y,说明降一层停靠更优。

反之,如果i+1层停靠,所有乘客爬的楼层数变成了N1+N2-N3,如果N1+N2-N3<Y说明升一层停靠更优。

书上给的程序就是用升楼的方式来判断的,也可以用降楼来动态规划最优楼层数。

 1 /*
 2 * 1.8.2动态规划
 3 *
 4 *  Created on: Jan 9, 2016
 5 *      Author: SeekHit
 6 */
 7 #include "iostream"
 8 #define N 100
 9
10 using namespace std;
11
12 int func(int n, int nPerson[]){
13
14     int nMinFloor=0, TargetFloor=1;
15     int N1=0,N2=nPerson[1],N3=0;
16
17 //计算N3,就停靠在1楼时,需要走的总楼层数
18     for (int i = 2; i <= n; i++){
19         N3+=nPerson[i];
20         nMinFloor+=nPerson[i]*(i-1);
21     }
22
23     for(int i=2;i<=n;i++){
24         if(N1+N2<N3){
25             TargetFloor=i;
26             nMinFloor+=(N1+N2-N3);
27             N1+=N2;
28             N2+=nPerson[i];
29             N3-=nPerson[i];
30         }
31         else
32             break;
33     }
34     return TargetFloor;
35 }
36
37 int main(){
38     int n, Target;
39     int nPerson[N];
40     cout<<"输入楼层总数n:"<<endl;
41     cin>>n;
42     cout<<"输入每层楼下的人数"<<endl;
43     for (int i = 1; i <= n; i++){
44         cout<<"第"<<i<<"层下的人数:"<<endl;
45         cin>>nPerson[i];
46     }
47
48     Target = func(n, nPerson);
49     cout<<"电梯停靠最优层数为:"<<Target<<endl;
50 }

运行结果:

扩展问题:

往上爬比往下走要累,往上爬一层消耗k个单位的能量,往下走只消耗1个单位的能量,求让所有人消耗的能量最少。

解法:

只需将计算N1+N2-N3变成N1+N2-N3*K即可。其余的都一样。

时间: 2024-09-29 22:08:27

编程之美 1.8小飞的电梯调度算法的相关文章

编程之美读书笔记1.8 - 小飞的电梯调度算法

http://blog.csdn.net/pipisorry/article/details/36688019 问题: 亚洲微软研究院所在的希格玛大厦一共有6部电梯.在高峰时间,每层都有人上下,电梯每层都停.实习生小飞常常会被每层都停的电梯弄的很不耐烦,于是他提出了这样一个办法: 由于楼层并不算太高,那么在繁忙的上下班时间,每次电梯从一层往上走时,我们只允许电梯停在其中的某一层.所有乘客从一楼上电梯,到达某层后,电梯停下来,所有乘客再从这里爬楼梯到自己的目的层.在一楼的时候,每个乘客选择自己的目

编程之美-小飞的电梯调度算法另一种解

放暑假了,在家闲着也是闲着,翻一翻去年买的<编程之美>这本书,有一些收获.昨天看到小飞的电梯调度算法这个问题,思考一番,得到了和书中给出的标准答案不一样的解决方法. 一.问题描述: 亚洲微软研究院所在的希格玛大厦一共有6部电梯.在高峰时间,每层都有人上下,电梯在每层都停.实习生小飞常常会被每层都停的电梯弄得很不耐烦,于是他提出了这样一个办法:由于楼层并不算太高,那么在繁忙的上下班时间,每次电梯从一层往上走时,我们只允许电梯停在其中的某一层.所有乘客从一楼上电梯,到达某层后,电梯停下来,所有乘客

第1章 游戏之乐——小飞的电梯调度算法

小飞的电梯调度算法 1. 问题描述: 亚洲微软研究院所在的希格玛大厦一共有6部电梯.在高峰时间,每层都有人上下,电梯每层都停.实习生小飞常常会被每层都停的电梯弄的很不耐烦,于是他提出了这样一个办法:由于楼层并不算太高,那么在繁忙的上下班时间,每次电梯从一层往上走时,我们只允许电梯停在其中的某一层.所有乘客从一楼上电梯,到达某层后,电梯停下来,所有乘客再从这里爬楼梯到自己的目的层.在一楼的时候,每个乘客选择自己的目的层,电梯则计算出应停的楼层. 问:电梯停在哪一层楼,能够保证这次乘坐电梯的所有乘客

【数学】小飞的电梯调度算法

题目:<编程之美>P53 若干个乘客从一楼上电梯,电梯出发后,只能停靠在某一层.问电梯停在哪一层,可以让所有乘客走的总楼层数最少? 分析: 电梯可以停在负层,但没有0层.所以程序返回0时,表示出错.这里有个陷阱,因为没有0层,所以在计算时,应该先把负数的楼层加1.当最后算出来的结果小于等于0时,再减去一,才是实际中的负数层数. 代码中输入的数组的元素,表示每个乘客想去的楼层.最佳停靠楼层肯定落在区间[minfloor,maxfloor],其中minfloor表示乘客想去楼层的最小值,maxfl

1.8 小飞的电梯调度算法

题目:有一栋楼,现在设计一种电梯调度算法:电梯在一楼让大家上电梯,然后根据大家选择要到的楼层算出某一楼层i,电梯在i层停下让所有人下电梯,然后大家爬楼梯达到自己的楼层.请问电梯停在哪一层,可以使得这一次的所有乘客爬楼层之和最短? (一) 最直接最简单的方法就是直接枚举从第一层到最后一层,然后算出电梯停在哪一层会使得所有乘客爬楼层之和最短. 代码如下: int nPerson[]; //nPerson[i]表示到第i层的乘客的数目 int nFloor = 0, nMinFloor = 0; in

读书问题之《编程之美》 -----12061161 赵梓皓

我阅读的书是<编程之美> 刚开始的时候阅读序,就觉得控制cpu利用率这个问题很好玩,所以重点看了这部分和解决办法,问题也都大部分是这部分的.那么问题就来了(挖掘机技术xxx?中国山东找蓝翔) 咳咳,问题在下面: 1.关于问题的提出.(也是一点点建议) 本书的主要内容是告诉读者如何思考问题和解决问题.但是提出问题也是很重要的,正如爱因斯坦所说“提出一个问题往往比解决一个问题更重要”,很多面试题(比如井盖为啥是圆的)我觉得正常人很少会想到.所以,这个问题是怎么想出来的...我很好奇.也希望作者能够

《编程之美》

自己也是才听老师的介绍,才从网上下载下<编程之美>这本书来阅读. 浏览其目录,发现这样的一本书正时我这个阶段所最需要的,现在大二,已经有了一定的基础,所以再看以前那些基础教程总觉得,太简单了.但是看太难的东西,又有好些知识没有学过,不理解.所以想<编程之美>这样一本,用到的知识比较基础,但是解题思路很新颖,可以开拓我们的视野,同时书中列出了源代码,只要自己愿意学习,可以迅速仿照例子做出程序,对于树立编程人员的自信心有很大帮助,同时短小的程序,可以迅速做出来,可以当做空闲时间的一种休

编程之美之饮料供货

在微软亚洲研究院上班,大家早上来的第一件事是干啥呢?查看邮件?No,是去水房拿饮料:酸奶,豆浆,绿茶.王老吉.咖啡.可口可乐--(当然,还是有很多同事把拿饮料当做第二件事). 管理水房的阿姨们每天都会准备很多的饮料给大家,为了提高服务质量,她们会统计大家对每种饮料的满意度.一段时间后,阿姨们已经有了大批的数据.某天早上,当实习生小飞第一个冲进水房并一次拿了五瓶酸奶.四瓶王老吉.三瓶鲜橙多时,阿姨们逮住了他,要他帮忙. 从阿姨们统计的数据中,小飞可以知道大家对每一种饮料的满意度.阿姨们还告诉小飞,

编程之美-分层遍历二叉树

问题:给定一个二叉树,要求按分层遍历该二叉树,即从上到下按层次访问该二叉树(每一层将单独输出一行),每一层要求访问的顺序为从左到右,并将节点依次编号.那么分层遍历如图的二叉树,正确的输出应该为: <span style="font-size:14px;">1 2 3 4 5 6 7 8</span> 书中还给出了问题2:打印二叉树中的某层次的节点(从左到右),其中根结点为第0层,成功返回true,失败返回false 分析与解法 关于二叉树的问题,由于其本身固有的