原帖地址:http://blog.csdn.net/li4951/article/details/7486092

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

解法一:暴力枚举法。从第1层枚举到第N层,求出电梯在x层停的话,所有乘客需要怕多少层楼。求出最少的那层即可。代码略。

解法二:动态规划。假设电梯停在第x层,已知目的楼层在x层的有N2人,在x层以下的有N1人,在x层以上的有N3人。此时总花费为sum。则往上走一层的话,总花费变为sum + N2 + N1 - N3。那么初始状态电梯停在第一层,向上进行状态的变迁,开始时N2 + N1 - N3 < 0。sum越来越小,直到某一层N2 + N1 >= N3,就没有必要在往上走了。这时已求出最合适的楼层了。

解法三:我的方法。哈哈。其实没有那么复杂。假设只有两个人,一个去9层,一个去2层,那么不管电梯停在2至9层中间的任何楼层,两个人的总花费都是7.就比如在数轴上点2和点9中间的任何点距离2和9的距离之后都是7。那么停在哪都无所谓了。接着我们扩展开来,假设有N个人,他们的目标楼层分别是2,3,3,4,5,5,5,7,7,8,9。按我们的想法,对于两端的(2,9)电梯只要停在他们之间都一样。同理对于(3,8)电梯只要停在他们中间都一样……。最终电梯只要停在中间那个数即可。也就是中位数。原来弄半天只需求出中位数即可啊。如果N是偶数个的话,停在中间那两个数任何一个都可以的。欢迎大家对我的解法拍砖。代码就不用了吧。

扩展问题的解法:
如果往上爬楼梯比较累,往下走较容易,假设往上走一层耗费k单位的能量,往下走一层只耗费1单位的能量。此时就不适合用我的解法三了,解法二更加适合。代码如下:

[cpp] view plaincopy
  1. int controlElevator(int nPerson[], int nfloor, int upWeight){
  2. int targetFloor = 1;
  3. int minFloor = 0;
  4. int N1 = 0;
  5. int N2 = nPerson[1];
  6. int N3 = 0;
  7. int i = 0;
  8. for(i = 2; i <= nfloor; i++){ //i表示大众意义上的第i层
  9. N3 += nPerson[i];
  10. minFloor += (nPerson[i] * (i - 1) * upWeight);
  11. }
  12. for(i = 2; i <= nfloor; i++){
  13. if(N1 + N2 < N3 * upWeight){
  14. minFloor += (N1 + N2 - N3 * upWeight);
  15. N3 -= nPerson[i];
  16. N1 += N2;
  17. N2 = nPerson[i];
  18. targetFloor = i;
  19. }
  20. else
  21. break;
  22. }
  23. return minFloor;
  24. //  return targetFloor;
  25. }

-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

原贴地址:http://blog.csdn.net/lonelycatcher/article/details/7910877

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

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

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

[cpp] view plaincopy
  1. /*
  2. * O(N^2)
  3. */
  4. int N;
  5. int nPerson[N+1];
  6. int target_floor;
  7. int min_floors = INT_MAX;
  8. for(i = 1;i<=N;i++)
  9. {
  10. int sum_floors = 0;
  11. for(j = 1;j<=N;j++)
  12. {
  13. sum_floors += nPerson[j] * abs(j - i);
  14. }
  15. if(sum_floors < min_floors)
  16. {
  17. min_floors = sum_floors;
  18. target_floor = i;
  19. }
  20. return (target_floor);
  21. }

方法二:书上提供的O(N)的动态规划的算法。

假设电梯停在i层楼,可以计算出所有乘客要爬楼层的层数为Y,假设此时有N1个乘客在i层楼以下,N2个乘客在I层楼,N3个乘客在I层楼以上,则当电梯停在i+1层的时候,N1+N2个乘客要多下一层楼,共多下N1+N2层,N3个乘客要少往上面爬一层楼,少上N3层楼,此时Y(i+1) = Y(i) + N1+N2-N3,很显然,当N1+N2<N3的时候,Y不断减小。Y1很容易算出来,另外我们还可以看出,N1+N2是递增的,N3是递减的,所以N1+N2一旦大于N3的时候,我们直接退出循环即可,没有必要再计算下去了。

[cpp] view plaincopy
  1. /*
  2. O(N)  dp
  3. */
  4. int N;
  5. int nPerson(N+1);
  6. int target_floor = 1;
  7. int min_floors = 0;
  8. int N1 = 0,N2 = nPerson[1],N3 = 0;
  9. for(i = 2;i<=N;i++)
  10. {
  11. min_floors += nPerson[i] * (i-1);
  12. N3 +=nPerson[i];
  13. }
  14. for(i = 2;i<=N;i++)
  15. {
  16. if(N1+N2 < N3)
  17. {
  18. target_floor = i;
  19. min_floors +=(N1+N2-N3);
  20. N1 +=N2;
  21. N2 = nPerson[i];
  22. N3 -=nPerson[i];
  23. }
  24. else
  25. break;
  26. }
  27. return target_floor;

方法三:中位数

其实这道题目仔细分析起来就是求一组数据的中位数而已。假设两人,分别到3层楼和8层楼下,在3和8之间取一点,使得到两个点距离最小,很显然,在3和8中的每一点到3和8的距离之和都是相等的。推广到2 3 5 5 6 7 8 8 9这样一组数据,target_floor为中位数。

[cpp] view plaincopy
  1. /*
  2. * mid_value
  3. *
  4. */
  5. int nPerson[N+1];
  6. int target_floor;
  7. int left = 1,right = N;
  8. while(right-left > 1)
  9. {
  10. while(nPerson[left] == 0)left++;
  11. nPerson[left] --;
  12. while(nPerson[right--] == 0)right--;
  13. nPerson[right] --;
  14. }
  15. return left;

扩展问题,往上爬一层要耗费K个单位的能量,往下走耗费1个单位的能亮,只需要计算N1+N2-N3变成N1+N2-N3*K即可。其余的都是一样的。

---------------------------------------------------------------------------------------------------------------------------------------------------------------

原帖地址:http://blog.csdn.net/zhanglei0107/article/details/8150437

设有N2个乘客在第i层下,N1个乘客的目的地楼层在第i层以下,N3个乘客的楼层在第i层以上

假设电梯从停在i层改停在为i+1层,停在第i层时消耗的总能量为E

则改为i+1层停之后原先i层以上的乘客即N3个乘客少往上爬一层,原先第i层的N2个乘客需多往下爬一层,原先第i层以下的N1个乘客需多往下爬一层。

所需总能量变为E-N3*K+N1+N2

若N3*K>(N1+N2),则停在i+1层好

若停第i层比停i+1层能量消耗低,会出现停第i层比停第i+2层能量消耗多的情况么

已知 N3*K<(N1+N2)

从i层到i+2层

消耗的能量变为E+2(N1+N2)+nPersons[i+1]-k(N3-nPersons[i+1])>E

因此循环只要有一次停第i层比停i+1层能量消耗低,后面变无需再比较

[cpp] view plaincopy
  1. //nPerson[i]表示到第i层的乘客数目
  2. //N1代表目标楼层在第i层以下的乘客数
  3. //N2代表目标楼层第i层的乘客数
  4. //N3代表目标楼层在第i层以上的乘客数
  5. void (int *nPerson,int k){
  6. int nMinEnergy=0;
  7. int nTargetFloor=1;
  8. int N1,N2,N3;
  9. int i;
  10. for(N1=0,N2=nPerson[1],N3=0,i=2;i<N;i++)
  11. {
  12. N3+=nPerson[i];
  13. nMinEnergy+=nPerson[i]*(i-1)*k;
  14. }
  15. for(i=2;i<N;i++)
  16. {
  17. if(N3*k>(N1+N2)){
  18. nTargetFloor=i;
  19. nMinEnergy=nMinEnergy-N3*K+N1+N2;
  20. N1=N1+nPerson[i-1];
  21. N3-=nPerson[i];
  22. N2=nPerson[i];
  23. }
  24. else
  25. break;
  26. }
  27. }

------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

【原创】编程之美---小飞的电梯调度问题 (停k层的解法)

问题.有一栋楼,一共有N层,要去每一层的人分别是A[1],A[2]....A[N],如果电梯可以停K次,问停在哪K层让所有人走的矩离最短?

[备注:这只是我的个人解法,欢迎和我讨论]

解法:
用一个数组opt[i][j]记录电梯前i次停在1到j层之间,所有人走的路的最短矩离。用cost[i][j]记录如果电梯从第i层到第j层只能停一次,电梯停在最佳位置让所有人走的矩离最短的最优解。那么cost[i][j]怎么求呢?(这里把这个解法省略,具体可参见编程之美“小飞的电梯调度”)。如果前i次停留在前j层,那么第i+1次停留在第j+1至j+k层(j+k<=n),则状态转移方程为
opt[i+1][j+k]=min{opt[i][j]+cost[j+1][j+k];} (k+j<=n)

Cost数组存放电梯从第i层到j层停一次的最小走动矩离,构造cost的代码如下:

for(i=1;i<=m;i++)

for(j=i;j<=m;j++)

{

cost[i][j] = 0;

mid = 求得电梯在i到j层的最佳停留位置;

for(k=i;k<=j;k++)

cost[i][j]+=(distance[mid]-distance[k])>=0 ?

distance[mid]-distance[k]:distance[k]-distance[mid];

}

Opt[i][j] 表示从电梯在第1层到第j层停i次所有人的最小走动矩离,对于i=1(即电梯只停一次的情况)来说,opt[i][j] = cost[i][j],如果让电梯在1 至 j层停两次,也就是i=2的情况,可能是下面一种情况的最优解:

第一次停在第一层,第二次停在2至j层;

第一次停在1至2层,第二次停在3至j层;

第一次停在1至3层,第二次停在4至j层;

等等。。。。。

该部分的代码如下:

for(i=0;i<=n;i++)

for(j=0;j<=m;j++)

if(opt[i][j]<Integer.max)

{

for(k=1;j+k<=m;k++)

{

if(opt[i+1][j+k]>opt[i][j]+cost[j+1][j+k])

{

opt[i+1][j+k] = opt[i][j]+cost[j+1][j+k];

}

}

}

编程之美----小飞的电梯调度算法相关推荐

  1. 编程之美---小飞的电梯调度问题 1.8 扩展2

    http://blog.163.com/guixl_001/blog/static/41764104201082062317857/ 问题.有一栋楼,一共有N层,要去每一层的人分别是A[1],A[2] ...

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

    小飞的电梯调度算法 电梯是我们每天都要坐的,上班高峰期是非常拥挤的,大家都不想每层都停,决定选择一层停,剩下的楼层大家自己爬.假设电梯共有N层,坐电梯的人有M人,每个人都有自己的目的层,现在让你设计一 ...

  3. 小飞的电梯调度算法,光影切割问题编程之美

    小飞的电梯调度算法: 1.8问题描述: 小飞是实习程序员,下班高峰期时电梯的每层都有人上下,等电梯是件烦人的事情. 小飞有个方案:电梯每次计算里面的人,和上的楼层,从而统计出在哪一层停,该上楼的出电梯 ...

  4. 1.8 小飞的电梯调度算法

    题目:有一栋楼,如今设计一种电梯调度算法:电梯在一楼让大家上电梯,然后依据大家选择要到的楼层算出某一楼层i,电梯在i层停下让全部人下电梯,然后大家爬楼梯达到自己的楼层.请问电梯停在哪一层.能够使得这一 ...

  5. java 电梯算法_编程之美之小飞的电梯调度算法(多种解法)---Java语言

    1.题目情景 我们假设都是从一楼上电梯的,而至于讯电梯停在其中的某一层.即所有的乘客都从一楼上电梯,到达某层之后,电梯停下来,所有乘客再从这里爬楼梯到自己的目的层.在一楼的时候,每个乘客选择自己的目的 ...

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

    问题:由于楼层并不高,在繁忙时段,每次电梯从一层往上走时,我们只允许停到其中某一层.所有乘客再从这层去往自己的目的楼层. 电梯停在哪一层,能够保证乘客爬楼梯之和最少? import java.util ...

  7. c语言 电梯调度,c语言函数如何返回两个值或多个值(结合 小飞 电梯调度算法)...

    正常思维:使用return 语句,但每调用一次函数 return 语句只能返回一个值 .这是C语言语法规则. 该怎么实现一个函数返回两个值或是多个值?,可以采用"间接方法".大概有 ...

  8. java 编程之美_《编程之美—微软技术面试心得》PDF 下载

    第1章 游戏之乐--游戏中碰到的题目 1.1 让CPU占用率曲线听你指挥 1.2 中国象棋将帅问题 1.3 一摞烙饼的排序 1.4 买书问题 1.5 快速找出故障机器 1.6 饮料供货 1.7 光影切 ...

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

    我阅读的书是<编程之美> 刚开始的时候阅读序,就觉得控制cpu利用率这个问题很好玩,所以重点看了这部分和解决办法,问题也都大部分是这部分的.那么问题就来了(挖掘机技术xxx?中国山东找蓝翔 ...

最新文章

  1. short_open_tag 必须打开
  2. python有什么作用-大数据学习之python语言有什么作用?
  3. Java 集合系列(三)Collection 接口
  4. css中padding和magin的区别
  5. AHK-UMSS框架 (AHK通用修饰键解决方案,任何键都是修饰键)
  6. 《和平精英》崩了 官方回应:受运营商网络波动影响 正在修复
  7. java udp丢包重发_UDPDataPacker_Java数据报之失序和丢包
  8. Google退出中国,谁的压力最大?
  9. LINUX安装TensorRT及特别注意事项
  10. 【转】Java集合间的相互转换
  11. win10 安装redis 解压版
  12. html图片与文字的排版6,前端开发学习笔记(六)- Css 文字排版
  13. linux安装lsi raid卡驱动下载,【LSIRAID卡驱动下载】LSIRAID卡官方驱动程序下载
  14. tableview设置footer会悬停在屏幕下方
  15. Excel演示神经网络原理(黑白数字0、1识别)
  16. google-auto之自动生成组件化文件
  17. 手机加密聊天软件功能文档(基于android系统)
  18. 让车机「下雨」,路特斯的智能座舱跑偏了吗?
  19. 1分鐘帶你了解最新區塊鏈支付系統「GuardPay 神盾支付」
  20. 酷6转型,陈天桥不认同视频业玩法

热门文章

  1. 期货成交量与持仓量图(期货持仓量成交量价格图解)
  2. 在线沙盒(恶意软件行为分析工具)整理介绍
  3. FPGA入门 Xilinx暑期学校学习Day2
  4. 深度剖析C语言结构体
  5. 给电视剧标注人脸的简单步骤:
  6. 第七周 任务一
  7. 应用“真心话大冒险”已更新到marketplace中
  8. response导出html到word
  9. Python开发实例:TPYBoard开发板制作声光控开关
  10. 华为面试应该怎么准备?