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

分析:

1)直接想法是穷举法,依次算出电梯停靠在第一层到第N层乘客所要爬的总层数,找出最小值。

代码(js版):

View Code
 1 var nPerson = new Array(0, 2, 3, 5, 8); //nPerson[i]表示第i层下的人数;
2
3 var N = 10; //电梯能到达的最大层数;
4
5 var nMinFloor, nTargetFloor; //nMinFloor为最小总层数;nTargetFloor为电梯停在哪层最优;
6
7
8 //解法一:穷举法 [时间复杂度O(N^2)]
9 function exhaustion()
10 {
11 var nFloor; //nFloor临时变量,记录每次的总层数;
12
13 nTargetFloor = -1;
14
15 //穷举电梯在每一层停靠的结果,比较结果得出最优解;
16 for(var i=1; i<=N; i++)
17 {
18 nFloor = 0;
19 for(var j=1; j<i; j++)
20 {
21 if(nPerson[j])
22 nFloor += nPerson[j]*(i-j);
23 else break;
24 }
25
26 //j=i的即那一层停靠的计算忽略掉,因为那一层的人不用动;
27
28 for(var j=i+1; j<=N; j++)
29 {
30 if(nPerson[j])
31 nFloor += nPerson[j]*(j-i);
32 else break;
33 }
34 if((nTargetFloor == -1) || (nMinFloor>nFloor))
35 {
36 nMinFloor = nFloor;
37 nTargetFloor = i;
38 }
39
40 }
41
42 alert("Minfloor acounts:"+ nMinFloor +", optTargetFloor:"+ nTargetFloor);
43 }

为降低时间复杂度,关键是减少嵌套for循环。

2)比较调整法(思路见注释)

View Code
 1 //解法二:比较法 [时间复杂度O(N)]
2 /*
3 思路:当电梯停靠在第i层时,乘客所要爬的总的楼梯数为Y.
4 假设有N1个乘客要到达的层数<i,有N2个乘客要到达的层数==i,有N3个乘客要到达的层数>i.
5 所以有:
6 (1)当电梯改停在i-1,则 Y+(N2+N3-N1)
7 (2)当电梯改停在i+1,则 Y+(N1+N2-N3)
8 所以当后面那部分的值<0时(如(2)的N1+N2<N3),则加上负数后总的楼梯数比原来的小,即更优解.
9 因此,我们可以从第一层开始,用以上策略,考察N1,N2,N3的值,依次调整以得到最优解.
10 */
11 function optCompared()
12 {
13 var N1, N2, N3, i;
14
15 nMinFloor = 0, nTargetFloor = 0;
16
17 //先计算好电梯停靠在第一层时N1,N2,N3以及总楼梯数nMinFloor.
18 for(N1=0, N2=nPerson[1], N3=0, i=2; i<=N; i++)
19 {
20 if(nPerson[i])
21 {
22 N3 += nPerson[i];
23 nMinFloor += nPerson[i]*(i-1);
24 }
25 else break;
26 }
27
28 //从电梯停靠在第一层开始考察
29 //比较N1,N2,N3,并调整N1,N2,N3,nTargetFloor和nMinFloor.
30 for(var i=2; i<=N; i++)
31 {
32 //N1+N2<N3即出现更优解时,则调整电梯停靠层数
33 if(N1+N2<N3)
34 {
35 nTargetFloor = i;
36 nMinFloor += N1+N2-N3;
37
38 //调整N1,N2,N3
39 N1 += N2;
40 N2 = nPerson[i];
41 N3 -= N2;
42 }
43 else break;
44 }
45
46 alert(nMinFloor +","+ nTargetFloor);
47
48 }


体会:

对比了自己的代码和书上的代码才发现就算思路相同,但是书上的代码的优化质量和简洁度显然更高。

嘿嘿,“优秀的代码是不知不觉中写出来的”。

路漫漫。

posted @ 2011-11-03 13:20  Quains  阅读(765)  评论(2编辑  收藏  举报
无觅相关文章插件,快速提升流量