ขว้างแมวออกไปนอกหน้าต่าง


150

ลองนึกภาพคุณอยู่ในอาคารสูงที่มีแมว แมวสามารถมีชีวิตรอดตกจากหน้าต่างชั้นต่ำ แต่จะตายหากถูกโยนลงมาจากชั้นสูง คุณจะรู้ได้อย่างไรว่าหยดที่ยาวที่สุดที่แมวสามารถอยู่รอดได้โดยใช้จำนวนครั้งน้อยที่สุด?

เห็นได้ชัดว่าถ้าคุณมีแมวเพียงตัวเดียวคุณก็สามารถค้นหาแบบเชิงเส้นได้ ก่อนโยนแมวจากชั้นแรก หากยังมีชีวิตอยู่ให้โยนออกจากวินาที ในที่สุดหลังจากถูกโยนจากพื้น f แมวจะตาย คุณจะรู้ว่าชั้น f-1 เป็นชั้นที่ปลอดภัยที่สุด

แต่ถ้าคุณมีแมวมากกว่าหนึ่งตัว ตอนนี้คุณสามารถลองค้นหาแบบลอการิทึมได้แล้ว สมมติว่าบิลด์มี 100 ชั้นและคุณมีแมวเหมือนกันสองตัว หากคุณโยนแมวตัวแรกออกจากชั้นที่ 50 แล้วคุณจะต้องค้นหา 50 ชั้นอย่างเป็นเส้นตรง คุณสามารถทำได้ดียิ่งขึ้นถ้าคุณเลือกชั้นล่างสำหรับความพยายามครั้งแรกของคุณ สมมติว่าคุณเลือกที่จะจัดการปัญหา 20 ชั้นในเวลาเดียวกันและชั้นที่ร้ายแรงที่สุดคือ # 50 ในกรณีนี้แมวตัวแรกของคุณจะรอดจากเที่ยวบินชั้น 20 และ 40 ก่อนตายจากชั้น 60 คุณเพียงแค่ต้องตรวจสอบชั้น 41 ถึง 49 ทีละตัว นั่นคือทั้งหมด 12 ครั้งซึ่งดีกว่า 50 อย่างที่คุณต้องการหากคุณพยายามกำจัดเลขฐานสอง

โดยทั่วไปแล้วกลยุทธ์ที่ดีที่สุดคืออะไรและมีความซับซ้อนในกรณีที่เลวร้ายที่สุดสำหรับอาคารที่ไม่มีแมวสองตัว แล้วสำหรับชั้น n และแมว m ล่ะ

สมมติว่าแมวทุกตัวมีค่าเท่ากันพวกมันทั้งหมดจะรอดชีวิตหรือตายจากการตกจากหน้าต่างที่กำหนด นอกจากนี้ความพยายามทุกอย่างเป็นอิสระ: หากแมวรอดชีวิตจากการตกสู่บาปมันก็ไม่เป็นอันตรายอย่างสมบูรณ์

นี่ไม่ใช่การบ้านแม้ว่าฉันอาจจะแก้ไขมันเพื่อการบ้านครั้งเดียว มันเป็นปัญหาที่แปลกที่โผล่เข้ามาในหัวของฉันในวันนี้และฉันจำไม่ได้ว่าวิธีแก้ปัญหา คะแนนโบนัสหากใครรู้ชื่อของปัญหานี้หรืออัลกอริทึมการแก้ปัญหา


123
ฉันคัดค้านการใช้แมวในลักษณะที่อธิบายไว้ เราสามารถเปลี่ยนเป็นสุนัขได้หรือไม่?
Thilo

53
มันไม่ง่ายอย่างนั้น การศึกษาได้ทำ (ของแมวโดยไม่ตั้งใจหลุดออกมาจากตึกระฟ้าไม่ถูกโยน) มีช่วงหนึ่งที่พวกมันตายและช่วงสูงกว่าที่พวกเขารอดชีวิตมาได้ มีบางอย่างเกี่ยวกับวิธีที่ทำให้ร่างกายเกร็ง
Andrew Shepherd

5
ฉันได้อ่านบางที่ที่ 15 ฟุตขึ้นไปแมวมีโอกาสรอดชีวิตมากกว่า คำถามนี้จะเหมาะกว่าถ้าเราทิ้งแฟนเก่าและ / หรือภรรยาที่จู้จี้
Anthony Forloney

34
คุณรู้ไหมว่าถ้าคุณเริ่มต้นด้วยแมวสองตัวคุณก็แค่รอสองสามเดือนแล้วทำการค้นหาแบบไบนารี่ หรือรอสองสามเดือนหลังจากนั้นและทำการ "ค้นหาพร้อมกัน" เพื่อที่คุณจะได้ผู้ช่วยในการโยนแมวจากทุก ๆ ชั้นพร้อมกัน - จำนวนแมวที่รอดตายในกรณีนั้นคือจำนวนชั้นสูงสุดที่คุณสามารถโยนได้ .
mjfgates

10
ด้วย bunnies ให้เปลี่ยน "เดือน" เป็น "สัปดาห์"
mjfgates

คำตอบ:


70

คุณสามารถเขียน DP (การเขียนโปรแกรมแบบไดนามิก) เล็กน้อยสำหรับกรณีทั่วไปของพื้น n และแมว m

สูตรหลักa[n][m] = min(max(a[k - 1][m - 1], a[n - k][m]) + 1) : for each k in 1..nควรอธิบายด้วยตนเอง:

  • หากแมวตัวแรกถูกโยนลงมาจากชั้น k-th และตายตอนนี้เรามีk - 1ชั้นให้ตรวจสอบ (ด้านล่างทั้งหมดk) และm - 1แมว ( a[k - 1][m - 1])
  • หากแมวยังมีชีวิตอยู่จะมีn - kชั้นเหลืออยู่ (ทุกชั้นด้านบนk) และยังคงเป็นmแมว
  • maxกรณีที่เลวร้ายที่สุดของทั้งสองควรจะเลือกจึง
  • + 1 มาจากความจริงที่ว่าเราเพิ่งใช้ความพยายามเพียงครั้งเดียว (ไม่ว่าแมวจะรอดชีวิตมาได้หรือไม่ก็ตาม)
  • min(f(k)) : for k in 1..nเราพยายามที่ชั้นเป็นไปได้ทุกที่จะหาผลที่ดีที่สุดจึง

เห็นด้วยกับผลลัพธ์ของ Google จากลิงก์ของGaurav Saxenaสำหรับ (100, 2)

int n = 100; // number of floors
int m = 20; // number of cats
int INFINITY = 1000000;

int[][] a = new int[n + 1][m + 1];
for (int i = 1; i <= n; ++i) {
    // no cats - no game
    a[i][0] = INFINITY;
}

for (int i = 1; i <= n; ++i) {
    for (int j = 1; j <= m; ++j) {
        // i floors, j cats
        a[i][j] = INFINITY;

        for (int k = 1; k <= i; ++k) {
            // try throw first cat from k-th floor
            int result = Math.max(a[k - 1][j - 1], a[i - k][j]) + 1;
            a[i][j] = Math.min(a[i][j], result);
        }
    }
}

System.out.println(a[n][m]);

คุณสามารถค้นหากลยุทธ์ได้อย่างง่ายดาย (วิธีโยนแมวตัวแรก) ถ้าคุณบันทึกได้ดีที่สุดkในอาเรย์อื่น

นอกจากนี้ยังมีวิธีแก้ปัญหาที่เร็วกว่าไม่เกี่ยวข้องกับการคำนวณ O (n ^ 3) แต่ตอนนี้ฉันก็ง่วงแล้ว

แก้ไข
อ้อใช่ผมจำได้ว่าที่ผมเห็นปัญหานี้มาก่อน


อืมไม่+ 1จำเป็นต้องอยู่ข้างนอกmin()เหรอ? เมื่อคุณพูดว่าตัวเองพยายามทำสำเร็จหรือไม่ก็ยังพยายามอยู่
j_random_hacker

@j_random_hacker มันเปลี่ยนอะไรไหม? ย้ายนอก+1 minหรือย้ายเข้าไปข้างในmax:)
Nikita Rybak

@ นิกิตะ: ฉันขอโทษที่ฉันทำผิดสิ่งที่คุณเขียน - สิ่งที่คุณมีอยู่ถูกต้องตามฉัน! +1
j_random_hacker

โปรดทราบว่านี่เป็นเช่นเดียวกับ "ปัญหาการตกไข่" ของ Google Code Jam โซลูชัน O (n ^ 3) ด้านล่างไม่ดีพอเนื่องจากชุดปัญหาขนาดใหญ่ใช้ N = 2000000000 code.google.com/codejam/contest/dashboard?c=32003#s=p2
ripper234

1
ดูคำถามใหม่นี้สำหรับอัลกอริทึม O (n) คำตอบยอดนิยมของ Google Code Jam คือ O (n) แต่ฉันยังไม่เข้าใจ stackoverflow.com/questions/4699067/…
ripper234

92

ตามตอนล่าสุดของ Radiolab (เกี่ยวกับ "Falling")แมวตัวหนึ่งมาถึงความเร็วเทอร์มินัลโดยชั้นที่ 9 หลังจากนั้นก็ผ่อนคลายและมีโอกาสน้อยที่จะเจ็บ มีแมวที่บาดเจ็บโดยสิ้นเชิงหลังจากตกจากที่สูงกว่า 30 ชั้นที่เสี่ยงที่สุดอยู่ที่ 5 ถึง 9


16
ในฐานะที่เป็นคนแมวฉันอยากจะชี้ให้เห็นว่าการศึกษาครั้งนี้มีพื้นฐานมาจากรายงานของโรงพยาบาลสัตว์หลังจากเหตุการณ์การทำลายล้าง ไม่มีแมวเพิ่มเติมที่ได้รับบาดเจ็บหรือไม่สะดวกในการสอบถามนี้
Thilo

16
ไม่ใช่คำตอบเพียงเพิ่มเติมบริบทจากโดเมนธุรกิจ
Thilo

19
มันเป็นคำตอบมากที่สุดเท่าที่คำถามสมควร
Mark Ransom

2
นี่เป็นเพียงการแสดงให้เห็นว่าไม่ใช่กรณีของการถ่ายทอดสด = 1, ตาย = 0 ตามผลลัพธ์ แต่การถ่ายทอดสด = 1.0, ตาย = 0.0 และทุกสิ่งในระหว่างนั้นคือความน่าจะเป็น นอกจากนี้ยังเป็นเส้นโค้งไม่ใช่เส้นที่ต้องค้นพบ
tadman

73
ปัญหาของรายงานนั้นคืออคติการเลือก - ไม่มีใครเอาแมวที่ตายไปหาสัตว์แพทย์
Niki Yoshiuchi

10

ลองนึกภาพคุณอยู่ในอาคารสูงที่มีแมว แมวสามารถมีชีวิตรอดตกจากหน้าต่างชั้นต่ำ แต่จะตายหากถูกโยนลงมาจากชั้นสูง คุณจะรู้ได้อย่างไรว่าหยดที่ยาวที่สุดที่แมวสามารถอยู่รอดได้โดยใช้จำนวนครั้งน้อยที่สุด?

กลยุทธ์ที่ดีที่สุดสำหรับการแก้ปัญหานี้คือการตรวจสอบโดยใช้กฎแห่งฟิสิกส์ความน่าจะเป็นที่สมมติฐานของคุณเป็นจริงตั้งแต่แรก

หากคุณทำเช่นนั้นคุณจะรู้ว่าโอกาสในการเอาชีวิตรอดของแมวเพิ่มระยะทางสู่พื้นดินที่สูงขึ้น แน่นอนว่าสมมติว่าคุณโยนมันจากอาคารที่สูงขึ้นเช่นหอคอยปิโตรนาไม่ใช่ภูเขาที่สูงกว่าเช่นภูเขาเอเวอร์เรสต์

แก้ไข:
จริงๆแล้วคุณจะเห็นการกระจายอูฐที่ยังไม่เสร็จ
ครั้งแรกความน่าจะเป็นของแมวที่ตายอยู่ในระดับต่ำ (ระดับความสูงต่ำมาก) จากนั้นจะสูงขึ้น (ระดับความสูงต่ำ) จากนั้นต่ำลงอีกครั้ง (ระดับความสูงที่สูงขึ้น) จากนั้นสูงขึ้นอีกครั้ง

กราฟสำหรับความน่าจะเป็นที่แมวจะตายในขณะที่ฟังก์ชั่นของความสูงเหนือพื้นดินมีลักษณะดังนี้:
(จบที่ 3 เนื่องจากการกระจายอูฐที่ยังไม่เสร็จ)

ข้อความแสดงแทน

อัปเดต:
ความเร็วเทอร์มินัลของแมวคือ 100 km / h (60mph) [= 27.7m / s = 25.4 yards / s]
ความเร็วเทอร์มินัลของมนุษย์คือ 210 km / h (130mph). [= 75m / s = 68.58 หลา / s]

เทอร์มินัลความเร็วเทอร์มินัลแหล่งที่มา:
http://en.wikipedia.org/wiki/Cat_righting_reflex

เครดิต:
Goooooogle

ฉันต้องตรวจสอบภายหลัง:
http://en.wikipedia.org/wiki/Terminal_velocity
http://www.grc.nasa.gov /WWW/K-12/airplane/termv.html



2
ถูกต้องหรือไม่ แน่นอนเมื่อถึงความเร็วเทอร์มินัลโอกาสไม่สามารถเปลี่ยนแปลงได้ - และฉันรู้สึกว่าแมวสามารถอยู่รอดได้เมื่อความเร็วเทอร์มินัลลดลง
ZoFreX

4
@ZoFreX: แน่นอนว่ามันเป็นความเร็วของเทอร์มินัลที่ร้ายแรงที่สุด ในทางกลับกันให้ปล่อยแมวออกมาพูดหนึ่งแสนไมล์ขึ้นไปและแมวก็มีแนวโน้มที่จะเผาไหม้ในชั้นบรรยากาศหลังจากตายจากสูญญากาศกว่าตกและอยู่
David Thornley

1
หูกระต่ายนั่นในกราฟนั้นเหรอ?
ninjalj

1
@ZoFreX: โมเมนตัมเชิงมุม แมววางเท้าอยู่เสมอเนื่องจากโมเมนตัมเชิงมุมเนื่องจากการออกแบบตัวของแมวและทักษะการพลิกของแมว แต่นั่นก็หมายความว่ามันต้องใช้เวลาในการเลี้ยว ยิ่งมีเวลามากขึ้น (==> ยิ่งระดับความสูงสูงขึ้น) ยิ่งแมวมีโอกาสมากขึ้นที่จะเหยียบ (==> โอกาสในการอยู่รอดเพิ่มขึ้นอย่างมากเมื่อเทียบกับการลงจอดบนหัว) แต่คุณพูดถูกความน่าจะเป็นยังคงเดิมหลังจากถึงความเร็วเทอร์มินัล ฉันจะบอกว่ามันน่าจะเป็นแมวที่สามารถอยู่รอดความเร็วตกเทอร์มินัลอย่างน้อยฉันกระโดดออกจากหน้าต่างห้องน้ำ (appx. 20m) โดยไม่มีรอยขีดข่วน
Stefan Steiger

8

ฉันก่อนอ่านปัญหานี้ในคู่มือการออกแบบอัลกอริทึมของ Steven Skiena (แบบฝึกหัด 8.15) มันตามบทที่เกี่ยวกับการเขียนโปรแกรมแบบไดนามิก แต่คุณไม่จำเป็นต้องรู้การเขียนโปรแกรมแบบไดนามิกเพื่อพิสูจน์ขอบเขตที่แม่นยำในกลยุทธ์ที่ ก่อนอื่นแถลงการณ์ปัญหาจากนั้นจึงแก้ปัญหาด้านล่าง

ไข่แตกเมื่อตกจากที่สูงพอสมควร เมื่อได้รับอาคาร n-story จะต้องมีชั้น f ซึ่งไข่จะตกลงมาจากการแตกของชั้น f แต่ไข่ที่ตกลงมาจากชั้น f-1 จะอยู่รอด (หากไข่แตกจากชั้นใด ๆ เราจะพูดว่า f = 1 ถ้าไข่อยู่รอดจากชั้นใดก็ได้เราจะพูดว่า f = n + 1)

คุณพยายามที่จะหาชั้นสำคัญ การผ่าตัดเพียงอย่างเดียวที่คุณทำได้คือวางไข่ลงบนพื้นและดูว่าเกิดอะไรขึ้น คุณเริ่มต้นด้วยไข่ k และหาวิธีวางไข่ให้น้อยที่สุดเท่าที่จะทำได้ ไข่ที่เสียจะไม่สามารถนำกลับมาใช้ใหม่ได้ (ไข่เหมือนเดิมสามารถ) ปล่อยให้ E (k, n) เป็นจำนวนขั้นต่ำของไข่ที่จะพอเพียง

  1. แสดงว่า E (1, n) = n
  2. E(k,n) = Θ(n**(1/k))แสดงให้เห็นว่า
  3. ค้นหาการเกิดซ้ำสำหรับ E (k, n) เวลาทำงานของโปรแกรมไดนามิกเพื่อค้นหา E (k, n) คืออะไร

เพียง 1 ไข่

วางไข่จากแต่ละชั้นเริ่มต้นที่แรกจะพบชั้นสำคัญในการดำเนินงาน (ที่แย่ที่สุด) n

ไม่มีอัลกอริทึมเร็วขึ้น ในเวลาใดก็ได้ในอัลกอริทึมใด ๆ ให้ชั้นสูงสุดที่ไข่ไม่ถูกทำลาย อัลกอริทึมจะต้องทดสอบชั้น g + 1 ก่อนชั้นที่สูงกว่า h> g + 1 ใด ๆ หากไข่แตกจากชั้น h มันไม่สามารถแยกความแตกต่างระหว่าง f = g + 1 และ f = h

2 ไข่

ก่อนอื่นมาพิจารณากรณีไข่ k = 2 เมื่อ n = r ** 2 เป็นสี่เหลี่ยมจัตุรัสที่สมบูรณ์ นี่คือกลยุทธ์ที่ใช้เวลา O (sqrt (n)) เริ่มต้นด้วยการวางไข่ครั้งแรกด้วยการเพิ่มขึ้นของชั้น r เมื่อไข่แตกตัวแรกพูดที่พื้นarเรารู้ว่าชั้นวิกฤติต้องเป็น(a-1)r < f <= arเช่นนั้น (a-1)rจากนั้นเราจะปล่อยไข่ที่สองจากแต่ละชั้นเริ่มต้นที่ เมื่อไข่ที่สองแตกเราจะพบชั้นวิกฤติ เราลดไข่แต่ละฟองในเวลา r ที่สุดดังนั้นอัลกอริทึมนี้ใช้การดำเนินการ 2r ที่แย่ที่สุดซึ่งก็คือΘ (sqrt (n))

เมื่อ n ไม่ตารางที่สมบูรณ์แบบใช้ r ceil(sqrt(n)) ∈ Θ(sqrt(n))= อัลกอริทึมยังคงΘ (sqrt (n))

พิสูจน์ว่าอัลกอริทึมใด ๆ ใช้เวลาอย่างน้อย sqrt (n) สมมติว่ามีอัลกอริทึมที่เร็วกว่า พิจารณาลำดับของชั้นที่มันลดไข่แรก (ตราบใดที่มันไม่แตก) เนื่องจากมันลดลงน้อยกว่า sqrt (n) จะต้องมีช่วงเวลาอย่างน้อย n / sqrt (n) ซึ่งคือ sqrt (n) เมื่อ f อยู่ในช่วงเวลานี้อัลกอริทึมจะต้องตรวจสอบกับไข่ตัวที่สองและจะต้องทำทีละชั้นเพื่อระลึกถึงกรณีตัวที่ 1 ไข่ ความขัดแย้ง.

k ไข่

อัลกอริทึมที่นำเสนอสำหรับ 2 ไข่สามารถขยายได้อย่างง่ายดายเพื่อ k ไข่ วางไข่แต่ละฟองด้วยช่วงเวลาคงที่ซึ่งควรนำมาเป็นพลังของราก kth ของ n ตัวอย่างเช่นสำหรับ n = 1,000 และ k = 3 ค้นหาช่วงเวลา 100 ชั้นด้วยไข่แรกและ 10 กับไข่ที่สองและ 1 กับไข่สุดท้าย

ในทำนองเดียวกันเราสามารถพิสูจน์ได้ว่าไม่มีอัลกอริทึมใดที่เร็วกว่าΘ(n**(1/k))โดยการเหนี่ยวนำจากการพิสูจน์ k = 2

ทางออกที่แน่นอน

เราอนุมานการเกิดซ้ำโดยปรับตำแหน่งที่จะวางไข่ครั้งแรก (ชั้น g) โดยสันนิษฐานว่าเรารู้วิธีที่ดีที่สุดสำหรับพารามิเตอร์ขนาดเล็ก หากไข่แตกเรามีชั้น g-1 ด้านล่างเพื่อสำรวจด้วยไข่ k-1 หากไข่ยังมีชีวิตอยู่เรามีชั้นเหนือที่จะสำรวจด้วยไข่ k มารเลือกสิ่งที่เลวร้ายที่สุดสำหรับเรา ดังนั้นสำหรับ k> 1 การเกิดซ้ำ

E(k,n) = min(max(E(k,n-g), E(k-1,g))) minimised over g in 1..n

หากฉันมีไข่ k ทำไมรันไทม์O(k*n**(1/k))สำหรับกรณีที่เลวร้ายที่สุดไม่ได้ เนื่องจากในกรณีที่เลวร้ายที่สุดฉันต้องผ่านช่วงเวลาที่n**(1/k) แน่นอน k
Rakete1111

2

สิ่งนี้ไม่ถือว่าคุณกำลังใช้ "The Same Cat" ใช่หรือไม่

คุณสามารถเข้าใกล้มันทางคณิตศาสตร์ แต่นั่นเป็นสิ่งที่ดีเกี่ยวกับคณิตศาสตร์ ... ด้วยสมมติฐานที่ถูกต้อง 0 สามารถเท่ากับ 1 (สำหรับค่าขนาดใหญ่ของ 0)

จากจุดที่ใช้งานได้จริงคุณสามารถได้รับ 'Similar Cats' แต่คุณไม่สามารถรับ "The Same Cat"

คุณสามารถลองหาคำตอบเชิงประจักษ์ได้ แต่ฉันคิดว่าจะมีความแตกต่างทางสถิติมากพอที่คำตอบนั้นจะไร้ความหมายทางสถิติ

คุณสามารถลองใช้ "The Same Cat" ได้ แต่นั่นไม่ได้ผลเช่นเดียวกับหลังจากหยดแรกมันไม่เหมือนแมวอีกต่อไป (ในทำนองเดียวกัน onecan ไม่เคยก้าวเข้าไปในแม่น้ำเดียวกันสองครั้ง)

หรือคุณสามารถรวมสุขภาพของแมวสุ่มตัวอย่างในช่วงเวลาที่ใกล้เคียงที่สุดและค้นหาความสูงที่แมวเป็น "ส่วนใหญ่มีชีวิตอยู่" (ตรงข้ามกับ "ส่วนใหญ่ตาย" จาก "เจ้าสาวเจ้าหญิง") แมวจะอยู่รอดโดยเฉลี่ย (จนถึงช่วงสุดท้าย)

ฉันคิดว่าฉันหลงทางจากความตั้งใจดั้งเดิม แต่ถ้าคุณไปตามเส้นทางเชิงประจักษ์ฉันลงคะแนนให้เริ่มต้นให้สูงที่สุดเท่าที่จะทำได้และวางแมวต่อไปเมื่อความสูงลดลงจนกว่าพวกมันจะอยู่รอดได้ในเชิงสถิติ และจากนั้นทดสอบแมวที่รอดชีวิตอีกครั้งเพื่อให้แน่ใจ


0

ฉันใช้วิธีที่แตกต่างออกไปเล็กน้อยในการสร้างวิธีแก้ปัญหา

ฉันเริ่มต้นด้วยการหาพื้นที่สูงสุดที่สามารถครอบคลุมได้โดยใช้x cat และyโดยใช้วิธีการต่อไปนี้

เริ่มต้นด้วย 1 ชั้นและเพิ่มจำนวนการคาดเดาในขณะที่ติดตามการตรวจสอบชั้นซึ่งเดาว่าพวกเขากำลังตรวจสอบและจำนวนแมวที่เหลือสำหรับแต่ละชั้น
ทำซ้ำถึงyครั้ง

นี้มากรหัสที่ไม่มีประสิทธิภาพในการคำนวณคำตอบที่ได้รับประโยชน์ แต่กระนั้นจำนวนเล็ก ๆ ของแมว / ชั้น

รหัสหลาม:

def next_step(x, guess):
  next_x = []
  for y in x:
    if y[0] == guess:
      if y[1] != 1:
        next_x.append((guess+1, y[1] - 1))
    next_x.append(y)
    if y[0] == guess:
      next_x.append((guess+1, y[1]))
  return next_x

x = [(1, TOTAL_NUM_CATS)]
current_floor = 1
while len(x) <= TOTAL_NUM_FLOORS:
  x = next_step(x, current_floor)
  current_floor += 1
  print len(x)

สำหรับแมว 2 ตัวชั้นสูงสุดที่สามารถระบุได้ในการเดา x คือ:
1, 3, 6, 10, 15, 21, 28 ...

สำหรับแมว 3 ตัว:
1, 3, 7, 14, 25, 41, 63 ...

สำหรับแมว 4 ตัว:
1, 3, 7, 15, 30, 56, 98 ...

หลังจากการวิจัย (ส่วนใหญ่ที่เกี่ยวข้องกับลำดับหมายเลขการพิมพ์ลงในOEIS ) ผมสังเกตเห็นว่าชั้นสูงสุดxดังต่อไปนี้รวมกันรูปแบบค่

สำหรับแมว 2 ตัว:
n <2: 2 ^ n - 1
n> = 2: C (n, 1) + C (n, 2)

สำหรับแมว 3 ตัว:
n <3: 2 ^ n - 1
n> = 3: C (n, 1) + C (n, 2) + C (n, 3)

สำหรับแมว 4 ตัว:
n <4: 2 ^ n - 1
n> = 4: C (n, 1) + C (n, 2) + C (n, 3) + C (n, 4)

จากที่นี่ฉันใช้วิธีง่าย ๆ ในการเพิ่ม n อย่างง่ายจนกระทั่งฉันผ่านจำนวนชั้นที่ต้องการ

รหัสหลาม:

def find_smallest(floors, eggs):
  maximum_floors = 0
  n = 0
  while maximum_floors < floors:
    maximum_floors = 0
    n += 1
    if n < eggs:
      maximum_floors = 2**n - 1
    else:
      count = 0
      for x in xrange(1, eggs+1):
        maximum_floors += combination(n, x)
  print n

นี่เป็นวิธีแก้ปัญหาที่ถูกต้องสำหรับ (100, 2) = 14.
สำหรับผู้ที่ต้องการตรวจสอบสิ่งเล็ก ๆ น้อย ๆ มันจะให้ (1 000 000, 5) = 43

สิ่งนี้จะทำงานใน O (n) โดยที่ n คือคำตอบของปัญหา (ยิ่งแมวยิ่งดี)
อย่างไรก็ตามฉันแน่ใจว่าคนที่มีระดับคณิตศาสตร์ที่สูงขึ้นสามารถลดความซับซ้อนของสูตรการคำนวณใน O (1)


0
O(m*(n^(1/m))) algorithm.

Let 'x' be the maximum number of attempts needed.  

m = 1 => linear => x=n

m = 2:  
Let the floors be split into 'k' partitions. The first cat is thrown at the end of each partition (max 'k' times). 
When it dies, the second cat is used to go up from the beginning of this partition.   
x = k + n/k.   
Minimize x by diff wrt k and setting = 0, to get k = n^(1/2) and x = 2 * n^(1/2).

m = 3:  
x = k + 2*(y^(1/2)), where y = n/k  
diff wrt x and set = 0, to get k = n^(1/3) and x = 3 * n^(1/3)

for general m:  
x = m * n^(1/m). 

-1

ฉันไม่สามารถอ่าน google blogspot เกี่ยวกับเรื่องนี้ (ต้องขอบคุณ blogwall ที่ใช้งานได้) แต่ฉันไม่คิดว่าการค้นหารูปแบบไบนารี่แบบตรงจะดีที่สุด สาเหตุที่การค้นหาแบบไบนารีนั้นยึดตามแนวคิดที่ว่าคำตอบที่คุณค้นหานั้นมีโอกาสเท่ากันที่ดัชนีดัชนีใด ๆ ในรายการ อย่างไรก็ตามในกรณีนี้นั่นไม่เป็นความจริง ในกรณีนี้คำตอบจะมีความน่าจะเป็นสูงกว่าที่จะอยู่ใกล้กับปลายด้านหนึ่งของช่วงมากกว่าอีกด้านหนึ่ง ฉันไม่รู้ว่าจะคำนึงถึงปัจจัยนั้นในการค้นหาอย่างไร แต่มันเป็นความคิดที่น่าสนใจ


1
ฉันคิดว่าคำถามกำลังถามกรณีที่เลวร้ายที่สุดดังนั้นการกระจายจึงไม่เกี่ยวข้องตราบเท่าที่ทุกชั้นเป็นไปได้
Steve Jessop

-1

ทั้งหมดนี้พูดถึงแมวที่บ้าคลั่ง .. และมันก็แค่เดาปัญหาจำนวนด้วยการเดาขั้นต่ำ (จำนวนของแมว) ไม่จำเป็นต้องมีการทำเทียม (และไม่ถูกต้อง) ให้นิยามอินฟินิตี้เป็นส่วนหนึ่งของการแก้ปัญหาเช่นกัน ตัวแปรควรได้รับการตั้งชื่อตามขอบเขตบนหรือสูงสุดลองหรือบางอย่างเช่น คำจำกัดความของปัญหา (เรื่องแมว) มีบางประเด็นที่ร้ายแรงแม้ว่าผู้คนจะตอบสนองต่อความโหดร้ายของสัตว์และหลายแง่มุมของปัญหาดังกล่าวที่เกิดขึ้นในชีวิตจริงเช่นอากาศ - ลากแรงโน้มถ่วงคือการเร่งความเร็วและพารามิเตอร์ชีวิตจริงอื่น ๆ ของปัญหา ดังนั้นบางทีมันควรถูกถามในวิธีที่แตกต่างกันโดยสิ้นเชิง


FWIW มันอาจเป็นปัญหาในชีวิตจริงที่ปลอมตัว สมมติว่าคุณมีการทดสอบอัตโนมัติที่ล้มเหลวในรุ่น 1234 แต่ทำงานได้กับรุ่น 42 แมวตายที่ 1234 แต่อยู่ที่รุ่น 42 การแก้ไขที่ฆ่ามัน หากอัปเดตจาก 42 เป็น 43 เป็นเรื่องง่ายและรวดเร็ว แต่การตรวจสอบและสร้างใหม่เวอร์ชันใหม่ยากนี่จะเริ่มดูเหมือนปัญหาของแมวมาก
mcdowella
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.