Bạn chọn ngẫu nhiên hai số nguyên khác nhau trong khoảng từ 1 đến 100. Xác suất để số lớn hơn chính xác gấp đôi số nhỏ hơn là bao nhiêu?


8

Gần đây tôi đã thực hiện bài kiểm tra HackerRank cho vị trí Khoa học dữ liệu và nhận được câu hỏi này sai. Tôi đã đến 1/200. Đây là cách thực hiện:

Có 50 kết hợp sẽ làm điều này đúng. (tức là {1,2}, {2,4}, {3,6} ... {50,100}). Xác suất của một số cụ thể được chọn là 1/100. Xác suất mà bộ cụ thể sẽ được chọn là (1/100 * 1/100).

Vì có 50 bộ,

P=50*(1/100)*(1/100)=1/200

Tất nhiên tôi cho rằng 1 và 100 được bao gồm. Nhưng đây là câu trả lời sai. Bất cứ ai có thể giúp tôi hiểu sai lầm của tôi?


4
Chìa khóa cho lỗi của bạn là từ "khác biệt".
Matthew Drury

À !! Vậy nó phải là 50 * (1/100) * (1/99)?
Jo Bennet

4
Giải quyết một phiên bản nhỏ hơn của vấn đề, chẳng hạn như thay thế "100" bằng "3". Làm điều đó bằng một bảng liệt kê đầy đủ của tất cả các cặp. Bạn nên nhanh chóng xem câu trả lời đúng là gì cho 100.
whuber

Câu trả lời:


7

Sai lầm đầu tiên của bạn là có 50 kết quả, thực tế là 100 (Chỉnh sửa: Xem bình luận bên dưới để làm rõ). Điều này là do nhận được (1,2) và (2,1) là kết quả của hai kết quả riêng biệt, nhưng trong mỗi trường hợp, số lớn hơn chính xác gấp đôi số nhỏ hơn.

Vì vậy, tổng số cách có thể để có được điều này thực sự được đưa ra bởi tập hợp:

{(1,2), (2,1), (2,4), (4.2), ..., (50.100), (100,50)}

Đó là danh sách 100 kết quả có thể xảy ra.

Tổng số kết quả có thể xảy ra là 100×99

Vì có 100 số có thể chọn lần đầu tiên và sau đó là 99 cho lần thứ hai vì chúng phải khác biệt.

Do đó, câu trả lời được đưa ra bởi:

P=100100×99=199

Sử dụng cùng một đối số, thật đơn giản để chứng minh rằng xác suất cho trường hợp tổng quát hơn là chọn các số từ trong đó n là một số chẵn dương được cho bởi:1,2,...,nn

P=1n1


1
n/2(n2)=(n/2)(n1)

6

"Hacker" trong tên của bài kiểm tra cho thấy chúng tôi cố gắng tìm một giải pháp định hướng điện toán.

Do đó, hãy bắt đầu với một chương trình liệt kê (a) các trường hợp "thuận lợi" trong đó một số nguyên gấp đôi số kia và (b) tất cả các trường hợp có thể. Câu trả lời sau đó sẽ là tỷ lệ của họ. Tôi đã mã hóa một giải pháp chung. Đầu vào của nó là một số nguyên dương nvà đầu ra của nó là xác suất.

n=100
all=favorable=0
for i=1 to n
    for j=1 to n
        if (i != j) all=all+1                  {1}
        if (j == 2*i) favorable = favorable+1  {2}
        if (i == 2*j) favorable = favorable+1  {3}
return(favorable / all)

(Bằng chứng về tính chính xác phụ thuộc vào thực tế là cho bất kỳ số dương nào .)i2ii

Chương trình này yêu cầu bài kiểm tra và tối đa tăng cho mỗi lần lặp của vòng lặp bên trong. Do đó, nó cần từ đến tính toán mỗi khi vòng lặp bên trong được thực hiện, hoặc tổng thể đến . Đó là hiệu suất : OK cho nhỏ như , nhưng khủng khiếp khi vượt quá hoặc hơn.333n6n3n26n2O(n2)nn=100n10000

Là một hacker, một trong những điều đầu tiên bạn sẽ muốn làm là loại bỏ hiệu suất bậc hai bằng cách đơn giản hóa vòng lặp bên trong (nếu có thể). Để kết thúc này, một cách có hệ thống đi qua các dòng trong vòng lặp bên trong (như được đánh số) và lưu ý những điều sau:

  1. Dòng 1 được thực hiện tất cả nhưng một lần cho mỗi giá trị ivà do đó allđược tăng lần. Do đó, để tính toán , vòng lặp có thể được thay thế bằng cách tăng theo .n1alljalln-1

  2. Dòng 2 được thực hiện chính xác một lần khi và mặt khác thì không. Do đó nó có thể được thay thế bằng incrementing bởi bất cứ khi nào .2inall12in

  3. Dòng 3 được thực thi khi được cung cấp ilà chẵn.

Đây là chương trình chuyển đổi.

n=100
all=favorable=0
for i=1 to n
    all = all + (n-1)                      {1'}
    if (2*i <= n) favorable = favorable+1  {2'}
    if (even(i)) favorable = favorable+1   {3'}
return(favorable / all)

Chúng ta có thể đi xa hơn và loại bỏ vòng lặp của nó?

  1. Dòng 1 'được thực hiện lần. Do đó được tăng lên bởi .nalln*(n-1)

  2. Dòng 2 'chỉ được thực hiện khi . Một cách để tính điều này là (số nguyên lớn nhất nhỏ hơn hoặc bằng ).2inn/2n/2

  3. Dòng 3 'chỉ được thực hiện cho các giá trị chẵn của . Một lần nữa, điều đó xảy ra lần.n / 2 in/2

Chuyển đổi thứ hai của chương trình là:

n=100
all=favorable=0                     {0}
all = all + n * (n-1)               {1''}
favorable = favorable + floor(n/2)  {2''}
favorable = favorable + floor(n/2)  {3''}
return(favorable / all)

Đây đã là một thành tựu to lớn: một thuật toán đã được giảm xuống một Thuật toán (có thể được coi là một "công thức khép kín" cho câu trả lời).O ( 1 )O(n2)O(1)

Cuối cùng, có một số phép biến đổi đại số đơn giản mà chúng ta có thể thực hiện bằng cách đưa phần khởi tạo (dòng 0) vào lần sử dụng đầu tiên của mỗi biến và kết hợp các dòng 2 '' và 3 '':

n=100
all = n * (n-1) 
favorable = 2 * floor(n/2) 
return(favorable / all)

Tại thời điểm này, một con người có thể thực hiện chương trình. Hãy làm điều đó với :n=100

all = 100 * (100-1) = 100*99
favorable = 2 * floor(100/2) = 2*50 = 100
favorable/all = 100 / (100*99) = 1/99

Do đó, đầu ra là .1/99

Tóm lại, một thuật toán brute-force có thể được chuyển đổi một cách có hệ thống bằng cách sử dụng các quy tắc viết lại chương trình đơn giản thành một chương trình đẹp, thanh lịch .O(1)


2

Trước hết, bạn đang lấy mẫu mà không cần thay thế. Do đó, có 100 * 99 kết quả khác nhau, ví dụ (1,1) không phải là kết quả hợp lệ.

Thứ hai, trật tự không quan trọng. Cái lớn hơn phải chính xác hai lần, không phải cái thứ hai. Do đó, loại bỏ các cặp đối xứng.

Do đó, 50 trong số (100) * 99/2 dương, hoặc 1/99

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.