小飛的電梯排程演算法@程式設計之美
阿新 • • 發佈:2019-01-28
題目:(程式設計之美 1.8)一棟樓有6層,現在設計一種電梯排程演算法:電梯在一樓讓大家上電梯,然後根據大家選擇要到的樓層算出某一樓層i,電梯在i層停下讓所有人下電梯,然後大家爬樓梯達到自己的樓層。請問電梯停在哪一層,可以使得這一次的所有乘客爬樓層之和最短?
思路:
1、暴力方法。依次停留在每一層,求出最小的爬樓梯數,時間複雜度為O(N*N);
2、假設停留在第i層,設此時往下走的為N1,停留在當前的為N2,往上走的步數為N3,那麼如果選擇i+1層,必須滿足條件(N2+N3)-N1>0,根據這個分析結果,可以不斷地調整。
3、這個題目還可以採用中位數的思想,根據1-6層可以看做求一個帶權陣列的加權平均數。
具體程式碼如下:
#include <iostream> using namespace std; const int INF = 1<<31 -1; //暴力演算法 int brute_force(int A[],int N) { int sum = INF; int tmp = 0; int itarget = 0; for(int i =0;i < N;i ++) { tmp = 0; for(int j = i-1;j >= 0;j --) { tmp += A[j]*(i-j); } for(int j = i+1;j < N;j ++) { tmp += A[j]*(j-i); } if(tmp < sum ) { sum = tmp; itarget = i; } } return itarget; } /* *N1為i層以下的人數 *N2為i層人數 *N3為i層以上的人數 *Y(i+1) = Y(i)+N3-N2-N1; */ int dynamic(int A[],int N) { int N1 = 0; int N2 = 0; int N3 = 0; int itarget = 0; N2 = A[0]; for(int i = 1;i < N;i ++) { N3 +=A[i]; } for(int i = 1;i < N;i ++) { if(N3 > N2 +N1) { N1 += N2; N2 = A[i]; N3 -= A[i]; itarget = i; } else break; } return itarget; } /* * *求加權中位數,這裡start是否是最終的解還有待商榷, *因為有可能是mend是最終解,所以後期還需要略微比較一下 */ int mymid(int A[],int N) { int mstart = 0; int mend = N-1; while (mend -mstart > 1) { while(A[mstart] == 0) mstart ++; A[mstart]--; while(A[mend] == 0) mend --; A[mend] --; } return mstart; } int main () { int A[]= {2,3,5,5,6,7,8,8,9}; cout << mymid(A,9); }
reference: