LCP 12. 小張刷題計劃
原題
為了提高自己的程式碼能力,小張制定了 LeetCode 刷題計劃,他選中了 LeetCode 題庫中的 n 道題,編號從 0 到 n-1,並計劃在 m 天內按照題目
編號順序刷完所有的題目(注意,小張不能用多天完成同一題)。
在小張刷題計劃中,小張需要用 time[i] 的時間完成編號 i 的題目。此外,小張還可以使用場外求助功能,通過詢問他的好朋友小楊題目的解法,
可以省去該題的做題時間。為了防止“小張刷題計劃”變成“小楊刷題計劃”,小張每天最多使用一次求助。
我們定義 m 天中做題時間最多的一天耗時為 T(小楊完成的題目不計入做題總時間)。請你幫小張求出最小的 T是多少。
示例 1:
輸入:time = [1,2,3,3], m = 2
輸出:3
解釋:第一天小張完成前三題,其中第三題找小楊幫忙;第二天完成第四題,並且找小楊幫忙。這樣做題時間最多的一天花費了 3 的時間,並且這個值是最小的。
示例 2:
輸入:time = [999,999,999], m = 4
輸出:0
解釋:在前三天中,小張每天求助小楊一次,這樣他可以在三天內完成所有的題目並不花任何時間。
限制:
1 <= time.length <= 10^5
1 <= time[i] <= 10000
1 <= m <= 1000
來源:力扣(LeetCode)
連結:https://leetcode-cn.com/problems/xiao-zhang-shua-ti-ji-hua
思路
Ⅰ. 這是一類題
最大化最小值,最大化平均值,最小化最大值…
這類題主要的方法就是二分答案/搜尋。
Ⅱ. 類似的題目
Ⅲ. 程式碼
- C++程式碼
class Solution {
private:
bool check(int mid, int m, vector<int> &time) {
// 所用天數, 總用時, 題耗時最多
// 這裡用了貪心的思想, 耗時最多的那個題目, 就場外求助
int days = 1, total = 0, maxCost = 0;
// 每天的場外求助是否被使用
bool use = true;
int size = time.size();
for (int i = 0; i < size; ++i) {
// 維護那個耗時最長的題的花費時間
maxCost = max(maxCost, time[i]);
// 總用時
total += time[i];
// 如果大於我給定的時間了
if (total > mid) {
// 如果有場外求助, 說明我今天還可以多解決一道題
if (use) {
total -= maxCost;
use = false;
} else {
// 如果沒有場外求助, 開啟下一天, 所有資訊清空
++days;
total = 0;
maxCost = 0;
--i;
use = true;
}
}
// 如果天數大於m了, 說明一天只有mid的時間不夠, 返回false
if (days > m) {
return false;
}
}
return true;
}
public:
int minTime(vector<int>& time, int m) {
int left = 0, right = 0;
// 左邊界=>0, 右邊界=>所有題的總時間
for (auto &it : time) {
right += it;
}
while (left <= right) {
int mid = left + (right - left) / 2;
// 每天用mid的時間可以完成嗎?
if (check(mid, m, time)) {
// 如果可以完成, 說明時間還可以減少
right = mid - 1;
} else {
// 如果不能完成, 說明時間不夠
left = mid + 1;
}
}
return left;
}
};
- Python程式碼
class Solution:
def check(self, mid, m, time):
use = True
days, total, maxCost = 1, 0, 0
size = len(time)
i = 0
while i < size:
maxCost = max(maxCost, time[i])
total += time[i]
if total > mid:
if use:
total -= maxCost
use = False
else:
days += 1
i -= 1
use, total, maxCost = True, 0, 0
i += 1
if days > m:
return False
return True
def minTime(self, time: List[int], m: int) -> int:
left, right = 0, sum(time)
while left <= right:
mid = (left + right) // 2
if self.check(mid, m, time):
right = mid - 1
else:
left = mid + 1
return left
特別注意:Python中在 for in range(size)
中修改i的值是沒有作用的,也強烈建議不要這樣子做
原因是因為 for
迴圈每次結束 i
都會被重新賦值。
Why can’t you modify lists through “for in” loops in Python?
總結
還是要多練習,做多了就好了,其餘幾道題解後面補上~
相關文章
- 12.設計模式設計模式
- 【筆試實戰】藍橋官網線上刷題100題計劃【第一輪】筆試
- 統計lcp各部分耗時
- leetcode刷題.763. 劃分字母區間.每日打卡LeetCode
- 演算法刷題:LeetCode中常見的動態規劃題目演算法LeetCode動態規劃
- 2024做題計劃
- 12.享元模式設計思想模式
- 刷題
- AtCoder ABCD做題計劃
- 遊覽計劃 題解
- 強基計劃 題解
- A計劃小程式的血與淚
- Nacos Committer 張龍:Nacos Sync 的設計原理和規劃MIT
- 刷題10.10
- LeetCode 刷題指南(一):為什麼要刷題LeetCode
- 九月補題計劃
- 想刷程式設計題找不到渠道?給你程式設計師專門的刷題網站!國內外都有程式設計師網站
- mysql刷題題後感MySql
- 程式設計師如何玩轉力扣刷題?程式設計師力扣
- iOS 開發刷題系列三:NSString 引用計數iOS
- MISC刷題12
- LeetCode 刷題—樹LeetCode
- LeetCode刷題 堆LeetCode
- 每日刷題 3.17
- 刷題學習
- 刷題記錄
- 順序刷題
- LeetCode刷題整理LeetCode
- leetcode刷題(一)LeetCode
- 如何做好專案管理,避免“計劃”和“執行”兩張皮?專案管理
- LCP 44. 開幕式焰火
- CF504E Misha and LCP on Tree
- LCP 07. 傳遞資訊
- 中考後刷題補題合集
- LeetCode刷題之第701題LeetCode
- 【APS】90張專業PPT學習高階計劃與排程(APS)
- 刷at 藍題日誌
- 2024.11.05 刷題訓練