小飞的电梯调度算法:
1.8问题描述:
小飞是实习程序员,下班高峰期时电梯的每层都有人上下,等电梯是件烦人的事情。
小飞有个方案:电梯每次计算里面的人,和上的楼层,从而统计出在哪一层停,该上楼的出电梯爬楼梯;该下楼的出电梯爬楼梯下去。
问题:电梯停靠在哪一层,能保证这次乘客爬楼梯的层数总和最少?
分析:
要算出乘客爬楼梯的层数最少。关键就是统计每次做电梯的人数,和楼层的总高度。
现在假设总共有N层,电梯停在第x层,到第i 层的人数为Tot[i];
需要走的层数为 sigma{Tot[i]*|x-i|};
解法一:从第一层开始计算,用枚举法x到第N层。O(N*N)
int p[]//p[i],表示到达i层的人数;
int MinFloor,TargetFloor,Floor;
TargetFloor=-1;
for(i=1;i<=N;++i){
Floor=0;
for(j=1;j<i;++j)
Floor=p[j]*(i-j);
for(j=i+1;j<=N;++j)
Floot=p[j]*(j-i);
if(TargetFloor==-1||MinFloor>Floor){
TargetFloor=i;
MinFloor=Floor;
}
}
return(TargetFloor,MinFloor);
时间复杂度O(N*N);
解法二:优化算法 时间复杂度O(N);
现在先规定到达抵达第i层乘客们一共需要爬Y层。到达第i层的有X2人,第i层以下x1人,到达第i层以上有x3人;
现在假设电梯在(i-1)层停下来,i层以下的人少走x1层;此时i层以上的人要多爬(x2+x3)层;
所以第(i-1)层停下时:Y-x1+x2+x3=Y-(x1-x2-x3)
同理在第(i+1)层停下时:多走x1+x2,少走x3 可得 Y+x1+x2-x3=Y-(x3-x1-x2)
当i层以下的人数比i层以上的人数和第i层人数之和大选在(i-1)层停。即x1>x2+x3
那么当x3>x1+x2时,在第(i+1)层停。
int p[]//p[i]表示需要在到达第i层的人数
int MinFloor,TargetFloor;
int x1,x2,x3;
MinFloor=0;
TargetFloor=1;
for(x1=0,x2=p[1],x3=0,i=2;i<=N;++i){//求出第i层,总共需要走Y层
x3+=p[i];
MinFloor+=p[i]*(i-1);
}
for(i=2;i<=N;++i){//for循环的功能是进行一层一层的枚举,上述那个(x1+x2<x3),
//选用第i+1层停。
if(x1+x2<x3){
MinFloor+=x1+x2-x3;
x1+=x2;
x2=p[i];
x3-=p[i];
}
break;
}
return(TargetFloor,MinFloor);
光影切割问题
1.7take note
问题描述:在cs游戏中的破旧仓库里。由于光线照射到地面,会形成光亮面和阴暗面。
如现在有三条光线照射在仓库里,地面形成了一块一块的光暗面,如图所示:1-8
现在的问题是:在x轴【a,b】的区间内,求出地面被分割的块数
解决方法:遇到这题,首先是试数,构造出模拟图,观察规律。
两条线,一个焦点,块数:4;
三条线,两个焦点,块数:6;
三条线,三个焦点,块数:7;
现在假设有N条线,M个交点;对于每增加一条线,假设就多了m个交点,把这条线分割成(m+1)段,每条线段会将原来的区域分割成两块,那么在原 来的基础上就多出了就多出了一块,因此新增了(m+1)块区域。那么N条线,M个交点,就分割成(M+N+1)个区域。
回归到本题,它问的是在区间【a,b】上分割的块数。可以转化为找区间【a,b】的交点数。