สมมติว่าเรามีกล้วย N กอง กองที่ i มีกล้วย ที่นี่ยามไปแล้วและจะกลับมาในชั่วโมง H Koko สามารถกำหนดความเร็วในการกินกล้วยต่อชั่วโมงของเธอได้คือ K ในแต่ละชั่วโมง เธอหยิบกล้วยกองหนึ่งไปกิน K กล้วยจากกองนั้น ถ้ากองกล้วยมีน้อยกว่า K เธอก็กินกล้วยทั้งหมดแทน และจะไม่กินกล้วยอีกในชั่วโมงนี้ คิดซะว่าโคโคะชอบกินช้าๆ แต่ก็ยังอยากกินกล้วยให้หมดก่อน รปภ.จะกลับมา เราต้องหาจำนวนเต็ม K ขั้นต่ำเพื่อให้เธอกินกล้วยหมดภายใน H ชั่วโมง
ดังนั้นหากอินพุตเป็น [3,6,7,11] และ H =8 เอาต์พุตจะเป็น 4
เพื่อแก้ปัญหานี้ เราจะทำตามขั้นตอนเหล่านี้ -
-
กำหนดวิธีการที่เรียกว่า ok() ซึ่งจะใช้อาร์เรย์ a สองค่า x และ h
-
เวลา :=0
-
สำหรับฉันอยู่ในช่วง 0 ถึงขนาดของ a
-
เวลา :=เวลา + a[i] / x
-
เวลา :=เวลา + i เมื่อ a[i] mod x เป็น 0
-
-
คืนค่าจริงเมื่อเวลา <=H
-
จากวิธีหลักให้ทำดังนี้
-
n :=ขนาดของอาร์เรย์ไพล์, set sum :=0, ต่ำ :=1, สูง :=0
-
สำหรับฉันอยู่ในช่วง 0 ถึง n – 1
-
สูง :=สูงสุดของกอง[i] และสูง
-
-
ในขณะที่ต่ำ <สูง
-
กลาง :=ต่ำ + (สูง – ต่ำ ) /2
-
ถ้า ok(piles, mid, H) เป็นจริง ให้ตั้งค่า high :=mid, มิฉะนั้น low :=mid + 1
-
ถ้า ok(piles, mid, H) เป็นจริง ให้ตั้งค่า high :=mid, มิฉะนั้น low :=mid + 1
-
-
ผลตอบแทนสูง
ให้เราดูการใช้งานต่อไปนี้เพื่อความเข้าใจที่ดีขึ้น -
ตัวอย่าง
#include <bits/stdc++.h>
using namespace std;
typedef long long int lli;
class Solution {
public:
bool ok(vector <int>& a, int x, int H){
int time = 0;
for(int i = 0; i < a.size(); i++){
time += a[i] / x;
time += (a[i] % x ? 1 : 0);
}
return time <= H;
}
int minEatingSpeed(vector<int>& piles, int H) {
int n = piles.size();
lli low = 1;
lli sum = 0;
lli high = 0;
for(int i = 0; i < n; i++)high = max((lli)piles[i], high);
while(low < high){
int mid = low + (high - low) / 2;
if(ok(piles, mid, H)){
high = mid;
}else{
low = mid + 1;
}
}
return high;
}
};
main(){
vector<int> v = {3,6,7,11};
Solution ob;
cout << (ob.minEatingSpeed(v, 8));
} อินพุต
[3,6,7,11] 8
ผลลัพธ์
4