《程式設計之美》小飛的電梯排程演算法
亞洲微軟研究院所在的希格瑪大廈一共有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單位的能量。此時就不適合用我的解法三了,解法二更加適合。程式碼如下:
int controlElevator(int nPerson[], int nfloor, int upWeight){
int targetFloor = 1;
int minFloor = 0;
int N1 = 0;
int N2 = nPerson[1];
int N3 = 0;
int i = 0;
for(i = 2; i <= nfloor; i++){ //i表示大眾意義上的第i層
N3 += nPerson[i];
minFloor += (nPerson[i] * (i - 1) * upWeight);
}
for (i = 2; i <= nfloor; i++){
if(N1 + N2 < N3 * upWeight){
minFloor += (N1 + N2 - N3 * upWeight);
N3 -= nPerson[i];
N1 += N2;
N2 = nPerson[i];
targetFloor = i;
}
else
break;
}
return minFloor;
// return targetFloor;
}
下面附上我的解法三的程式碼:
int main(){
int nPerson[9]={0,1,1,0,2,1,1,2,1};
int left=0, right=8;
while(right-left > 1){
while(nPerson[left] == 0)
++left;
nPerson[left]--;
while(nPerson[right] == 0){
if(right < left)
break;
--right;
}
nPerson[right]--;
}
cout<<left+1<<endl;
return 0;
}
相關推薦
《程式設計之美》讀書筆記之[小飛電梯排程演算法]
在高峰時間,實習生小飛常常會被電梯每層樓都停弄得很不耐煩,於是他想出了這樣一個辦法:由於樓層並不高,那麼在繁忙的時間,每次電梯從一層往上走時,我們只允許電梯停在其中的某一層。所有乘客都從一樓上電梯,到達某層樓後,
程式設計之美之小飛的電梯排程演算法(多種解法)---Java語言
1.題目情景 我們假設都是從一樓上電梯的,而至於訊電梯停在其中的某一層。即所有的乘客都從一樓上電梯,到達某層之後,電梯停下來,所有乘客再從這裡爬樓梯到自己的目的層。在一樓的時候,每個乘客選擇自己的目的層,電梯則自動計算出應停的樓層,並且能夠保證該層停使得所有
《程式設計之美》小飛的電梯排程演算法
亞洲微軟研究院所在的希格瑪大廈一共有6部電梯。在高峰時間,每層都有人上下,電梯每層都停。實習生小飛常常會被每層都停的電梯弄的很不耐煩,於是他提出了這樣一個辦法: 由於樓層並不算太高,那麼在繁忙的上下班時間,每次電梯從一層往上走時,我們只允許電梯停在其中的某一層
程式設計之美 1.8小飛的電梯排程演算法的第三種解
原題目如下: 亞洲微軟研究院所在的希格瑪大廈一共有6部電梯。在高峰時間,每層都有人上下,電梯每層都停。實習生小飛常常會被每層都停的電梯弄的很不耐煩,於是他提出了這樣一個辦法: 由於樓層並不算太高,那麼在繁忙的上下班時間,每次電梯從一層往上走時,我們只允許電梯停在其中的某
小飛的電梯排程演算法@程式設計之美
題目:(程式設計之美 1.8)一棟樓有6層,現在設計一種電梯排程演算法:電梯在一樓讓大家上電梯,然後根據大家選擇要到的樓層算出某一樓層i,電梯在i層停下讓所有人下電梯,然後大家爬樓梯達到自己的樓層。請問電梯停在哪一層,可以使得這一次的所有乘客爬樓層之和最短? 思路: 1、暴
程式設計之美1.8小飛的電梯排程演算法擴充套件問題
設有N2個乘客在第i層下,N1個乘客的目的地樓層在第i層以下,N3個乘客的樓層在第i層以上 假設電梯從停在i層改停在為i+1層,停在第i層時消耗的總能量為E 則改為i+1層停之後原先i層以上的乘客即N3個乘客少往上爬一層,原先第i層的N2個乘客需多往下爬一層,原先第i層以下
程式設計之美--遊戲之樂--1.8小飛的電梯排程問題
o(n)解法 利用Y來儲存以當前i層為基準,所有員工需要走的樓層 N1 i層以下所有人數 N2 第i層的人數 N3 i層以上的人數 可以得出: Y = Y(i-1需要走的樓層)+N1-N2
程式設計之美---電梯排程演算法
在看linux 0.11版本的塊裝置驅動部分,裡面提到了電梯演算法,總結下幾種尋道的方式。 第一種:最為原始的先到先服務(first come first served)的演算法。假設此時我們正在第11道讀取資料,然後陸陸續續有其他程序來要求我們提供磁碟內容
小飛的電梯排程演算法
1、問題描述: 某大廈一共有6部電梯,在高峰時間,每層都有人上下,電梯在每層都停,實習生小飛常常會被每層都停的電梯弄的很不耐煩,於是他提出了這樣一個辦法:由於樓層不太高,每次電梯往上走時,我們只允許電
程式設計之美電梯排程問題
電梯排程問題:亞洲微軟研究院所在的希格瑪大廈一共有6部電梯。在高峰時間,每層都有人上下,電梯每層都停。實習生小飛常常會被每層都停的電梯弄的很不耐煩,於是他提出了這樣一個辦法: 由於樓層並不算太高,那麼在繁忙的上下班時間,每次電梯從一層往上走時,我們只允許電梯停在其中的
最長遞增子序列程式設計之美232演算法
#include <stdio.h> #include <stdlib.h> int a[100];//儲存原始序列 int LIS[100];//儲存以a[i]為最大元素的最長遞增子序列的長度 int MaxV[100];//儲存長度為i的遞增子序
程式設計之美——一摞烙餅的排序(暴搜+剪枝)
題目 分析 深度優先搜尋遍歷每一種情況,去翻轉次數最小的,當然,還要加一些剪枝,畢竟O(nn)的時間複雜度。 程式碼 C風格 1 /**** 字首排序 ****/ 2 #include<stdio.h> 3 #include<cstring> 4 #incl
電梯排程演算法認識
傳統電梯排程演算法 1.1先來先服務演算法(FCFS) 先來先服務(FCFS-First Come First Serve)演算法,是一種隨即服務演算法,它不僅僅沒有對尋找樓層進行優化,也沒有實時性的特徵,它是一種最簡單的電梯排程演算法。 它根據乘客請求乘坐電梯的先後次序進行排程。
程式設計之美10:計算字串的相似度
我們並不在乎兩個字串變得相等之後的字串是怎樣的,所以 1.一步操作之後,再將A[2,…,lenA]和B[1,…,lenB]變成相同的字串。 2.一步操作之後,再將A[1,…,lenA]和B[2,…,lenB]變成相同的字串。 3.一步操作之後,再將A[2,…,lenA]和B[2,…,lenB]變成相
程式設計之美9:陣列迴圈位移
1: RightShift(int *arr, int N, int K) { K %= N; while (K--) { int t = arr[N - 1]; for (int i = N - 1; i > 0; i--)
程式設計之美8:求陣列的子陣列之和的最大值
1: int MaxSum(int *A, int n) { int maximum = -INF; int sum; for (int i = 0; i < n; i++) { sum = 0; for (int j = i;
程式設計之美7:最大公約數
1:輾轉相除法 f(x,y) = f(y, x%y); int gcd(int x, int y) { return (!y) ? x : gcd(y, x % y); } 2:對於大整數,取模運算非常昂貴。 f(x, y) = f(x-y, y); BigInt gcd(BigI
程式設計之美3:求二進位制數中1的個數
1: int Count(BYTE v) { int num = 0; while (v) { if (v % 2 == 1) { num++; } v = v / 2; }
程式設計之美2:程式只用一個位元組變數,列印將帥位置
原創:https://blog.csdn.net/ndzjx/article/details/84404320 #include <stdio.h> #include <windows.h> #include <time.h> #include <
程式設計之美1:CPU列印直線,曲線
原創:https://blog.csdn.net/ndzjx/article/details/84404268 1:本質:每次迴圈的CPU比例問題。 CPU排程時間片,大約為20ms 2.2GHz是CPU時鐘週期,= 22億次 = 2.2*10^9 每個時鐘週期平均執行2條彙編指令