สมมติว่าเราให้ไข่ K และเรามีอาคารที่มีชั้น N ตั้งแต่ 1 ถึง N ตอนนี้ไข่แต่ละฟองมีหน้าที่เหมือนกัน และถ้าไข่แตก เราจะไม่ทิ้งมันอีก
มีชั้น F ที่มีค่าระหว่าง 0 ถึง N โดยที่ไข่ที่ตกที่ชั้นที่สูงกว่า F จะแตก และไข่ที่ตกที่หรือต่ำกว่าชั้น F จะไม่แตก ในแต่ละการเคลื่อนไหว เราอาจเอาไข่หนึ่งฟองแล้ววางจากชั้น X ใดก็ได้ X อยู่ในช่วง 1 ถึง N
เป้าหมายของเราคือต้องรู้ว่าค่า F คืออะไร ดังนั้นจำนวนการเคลื่อนไหวขั้นต่ำที่เราจำเป็นต้องรู้อย่างมั่นใจว่า F คืออะไรโดยไม่คำนึงถึงค่าเริ่มต้นของ F จะเป็นเท่าใด
ดังนั้น หากอินพุตเป็น K =2 และ N =6 เอาต์พุตจะเป็น 3
เพื่อแก้ปัญหานี้ เราจะทำตามขั้นตอนเหล่านี้ -
-
กำหนดอาร์เรย์ 2 มิติหนึ่ง dp
-
กำหนดฟังก์ชัน Solve() ซึ่งจะใช้ K, N
-
ถ้า N <=1 แล้ว −
-
กลับ N
-
-
ถ้า K เท่ากับ 1 แล้ว −
-
กลับ N
-
-
ถ้า dp[K, N] ไม่เท่ากับ -1 แล้ว −
-
กลับ dp[K, N]
-
-
ret :=N ต่ำ :=0, สูง :=N
-
ในขณะที่ต่ำ <=สูง ทำ -
-
ซ้าย :=1 + แก้ (K - 1, กลาง - 1)
-
ขวา :=1 + แก้ (K, N - กลาง)
-
ret :=ต่ำสุดของ ret และสูงสุดของซ้ายและขวา
-
ถ้าซ้ายเท่ากับขวา −
-
ออกจากวง
-
-
ถ้าซ้าย <ขวา แล้ว:
-
ต่ำ :=กลาง + 1
-
-
สูงอย่างอื่น :=กลาง - 1
-
-
กลับ dp[K, N] =ret
-
จากวิธีหลักให้ทำดังต่อไปนี้ -
-
dp :=สร้างอาร์เรย์ 2 มิติ (K + 1) x (N + 1) หนึ่งชุด เติมด้วย -1
-
กลับแก้(K, N)
ให้เราดูการใช้งานต่อไปนี้เพื่อความเข้าใจที่ดีขึ้น -
ตัวอย่าง
#include <bits/stdc++.h>
using namespace std;
class Solution {
public:
vector<vector<int>> dp;
int solve(int K, int N) {
if (N <= 1)
return N;
if (K == 1)
return N;
if (dp[K][N] != -1)
return dp[K][N];
int ret = N;
int low = 0;
int high = N;
while (low <= high) {
int mid = low + (high - low) / 2;
int left = 1 + solve(K - 1, mid - 1);
int right = 1 + solve(K, N - mid);
ret = min(ret, max(left, right));
if (left == right)
break;
if (left < right) {
low = mid + 1;
} else
high = mid - 1;
}
return dp[K][N] = ret;
}
int superEggDrop(int K, int N) {
dp = vector<vector<int>>(K + 1, vector<int>(N + 1, -1));
return solve(K, N);
}
};
main(){
Solution ob;
cout << (ob.superEggDrop(2,6));
} อินพุต
2, 6
ผลลัพธ์
3