乙個演算法問題,100號乘客找到正確座位的概率

2021-08-19 19:45:52 字數 4058 閱讀 3053

大一的時候,表哥發給我幾個問題,有乙個還記得大概內容,但是不記得當時是否解決了,當時沒有用程式給實現出來,用數學推的。

突然記起來了,就寫點**試了下,現在記錄下。。。

問題描述:

有乙個飛機有100個座位,飛機票被賣給了100個乘客,乘客必須順序依照自己的編號就坐。如果自己的位置被別人占用了,就隨機在剩下的空座位中找乙個坐下。正常情況下,就是1號乘客坐1號座位,2號乘客坐2號座位,以此類推。

可是現在1號乘客是個瘋子,他隨便找了個座位坐下(不一定是1號座位)。現在問第100號乘客坐到自己座位的概率是多少?

我用 python 寫了段**,列印的結果是接近 0.5。

而且奇怪的發現,當乘客總數=座位總數=1時,這個概率為1,否則,最後乙個乘客坐到自己座位的概率都為0.5左右。後來發現這個值的原因應該跟 馬爾科夫不等式 有關。

解題思路:

1. 第100號座位必定會被人坐到,而且是在這100個乘客中的某個人。

2. 那麼所有乘客坐到第100座位的概率之和應該是1.

依次分析 1號乘客坐到100號座位的概率是 0.01, 2號乘客坐到100號座位的條件是1號乘客佔了2號的位子,2號選擇了100號座位坐下,概率是(1/100)*(1/99), 3號乘客坐到 100 號座位的條件是前面2個人有人坐了他的位子,他去坐100號座位。否則他就要去坐3號自己的位置。

使用 python3.6的**實現如下:

def showlist(la):

print("---------showlist-----------")

print("[")

s = ''

for i in range(len(la)):

if i % 10 == 0:

s += "["

s += ''.format(la[i])

if (i+1) % 10 == 0:

print(s + "]")

s = ''

else:

s += ", "

print(s+ "]")

seats = [0 for i in range(100)]

seats[0] = 1.0/len(seats)

for i in range(len(seats)-1):

for j in range(i):

temp = seats[j] * (1.0/(len(seats) - i))

seats[i] += temp

# 為確保總概率為1,目標位置的概率最好為1.0減去前面的人坐目標位置的概率

seats[len(seats)-1] = 1.0-sum(seats)

showlist(seats)

列印結果:

---------showlist-----------

[0.01000, 0.00010, 0.00010, 0.00011,0.00011, 0.00011, 0.00011, 0.00011, 0.00012, 0.00012]

[0.00012, 0.00012, 0.00013, 0.00013,0.00013, 0.00014, 0.00014, 0.00014, 0.00015, 0.00015]

[0.00015, 0.00016, 0.00016, 0.00017,0.00017, 0.00018, 0.00018, 0.00019, 0.00019, 0.00020]

[0.00020, 0.00021, 0.00021, 0.00022,0.00023, 0.00023, 0.00024, 0.00025, 0.00026, 0.00026]

[0.00027, 0.00028, 0.00029, 0.00030,0.00031, 0.00032, 0.00034, 0.00035, 0.00036, 0.00038]

[0.00039, 0.00041, 0.00043, 0.00044,0.00046, 0.00048, 0.00051, 0.00053, 0.00055, 0.00058]

[0.00061, 0.00064, 0.00067, 0.00071,0.00075, 0.00079, 0.00084, 0.00089, 0.00095, 0.00101]

[0.00108, 0.00115, 0.00123, 0.00132,0.00142, 0.00154, 0.00167, 0.00181, 0.00198, 0.00216]

[0.00238, 0.00263, 0.00292, 0.00327,0.00368, 0.00417, 0.00476, 0.00549, 0.00641, 0.00758]

[0.00909, 0.01111, 0.01389, 0.01786,0.02381, 0.03333, 0.05000, 0.08333, 0.16667, 0.50000]

當調整座位和乘客人數為10時,結果還是0.5:

---------showlist-----------

[[0.10000, 0.01111, 0.01389, 0.01786, 0.02381, 0.03333, 0.05000, 0.08333, 0.16667, 0.50000]

如果,這時,需求改為求第50個乘客坐到自己位置的概率呢?此時,可以把上述**改為如下,即可列印出所有乘客坐到自己座位的概率,並且此時乘客總數不必等於座位總數,只要按原規則坐即可。

**如下:

#----------------------------

def showlist(la):

print("---------showlist-----------")

print("[")

s = ''

for i in range(len(la)):

if i % 10 == 0:

s += "["

s += ''.format(la[i])

if (i+1) % 10 == 0:

print(s + "]")

s = ''

else:

s += ", "

print(s+ "]")

# 求出第 peoplenum 個人(從1開始,人和座位編號是從0開始的)找到自己位置的概率,

# totalseatsnum 是座位總數

def getpsit2targetseat(peoplenum, totalseatsnum):

pseats = [0 for i in range(peoplenum)]

pseats[0] = 1.0/totalseatsnum

for i in range(peoplenum - 1):

for j in range(i):

temp = pseats[j] * (1.0/(totalseatsnum - i))

pseats[i] += temp

if peoplenum > 1:

pseats[peoplenum - 1] = 1- sum(pseats)

#showlist(pseats)

return pseats[peoplenum - 1]

# 獲取每個人坐到自己座位的概率的列表,totalseatsnum是總座位數

def getprobilityofeveryonesetselfseat(totalseatsnum):

p =

for i in range(totalseatsnum):

return p

seats_num = 10 # 總座位數

#t_num = 10

#print(getpsit2targetseat(t_num, seats_num))

showlist(getprobilityofeveryonesetselfseat(seats_num))

--------------------------分割線

上面**以10為例,列印結果是:

---------showlist-----------

[[0.10000, 0.90000, 0.88889, 0.87500, 0.85714, 0.83333, 0.80000, 0.75000, 0.66667, 0.50000]

]

乙個演算法問題

今天上午上班由於沒什麼事做,就看看書,發現乙個演算法問題,開始看感覺貌似很簡單,但是越想越有意思。1,題目描述 給定乙個十進位制的正整數n,寫下從1開始到n所有出現 1 的個數。例如 n 2 寫下 1 2 出現了乙個1 n 12,寫下1,2,3,4,5,6,7,8,9,10,11,12.這樣1的個數...

乙個布局演算法問題解析

已知條件 寬度已知且有限,高度無限的區域內,有n個方格,已知這些方格的x y 座標以及寬度w和高度h,方格不重疊 需求 在空間內找個乙個位置,可以放的下乙個固定寬高 如4 x 4 的方格,原則 離原點最近且y軸最上 關鍵點 位置資訊轉化為二維陣列 目標點 每個已知方格的左下角點 a,右下角點 b,和...

求助 乙個彩票的演算法問題 !

知識前提 這個是 3d 的玩法 簡單先了解下!什麼叫組3 什麼叫組6 什麼叫豹子 豹子就是三個位置數字相同的號碼,總共十注 000 111 222 直到999。直選號碼確定數字位置 組選號碼不需確定號碼位置。組選三就是三個數字中有兩個相同,比如說你買組選三055 對應055 505 550三注直選號...