[每日一题] leetcode LCP 12. 小张刷题计划

135 阅读2分钟

携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第8天,点击查看活动详情

LCP 12. 小张刷题计划

为了提高自己的代码能力,小张制定了 LeetCodeLeetCode 刷题计划,他选中了 LeetCodeLeetCode 题库中的 nn 道题,编号从00n1n-1,并计划在 mm 天内按照题目编号顺序刷完所有的题目(注意,小张不能用多天完成同一题)。

在小张刷题计划中,小张需要用 time[i]time[i] 的时间完成编号 ii 的题目。此外,小张还可以使用场外求助功能,通过询问他的好朋友小杨题目的解法,可以省去该题的做题时间。为了防止“小张刷题计划”变成“小杨刷题计划”,小张每天最多使用一次求助。

我们定义 mm 天中做题时间最多的一天耗时为 TT(小杨完成的题目不计入做题总时间)。请你帮小张求出最小的 TT 是多少。

示例 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
思路

题目要求 TT 尽可能小。
考虑这样一个问题,什么时候 TT的满足情况的?
设当 TT 当前为 xx, 且满足可以在mm天内完成。
显然,x+1,x+2,x+3,....x+1, x+2, x+3, .... 都是满足这一条件的
若是 xx 为最后答案,则一定满足如下条件:
小于xx的一定不满足在mm天内完成,大于等于xx的值一定满足条件
所以根据条件可以把整个 集合划分为两部分
对于区间被分成两部这种情况,要找到中间的分界点。
我们可以采用二分去逐步逼近
下一个问题,如何检查xx的合法性?
我们由于只能顺序的完成任务,那么这就给我们可操作空间比较小
只需要顺序的贪心完成就可以了。
注意,“今天“ 内可以完成很多件任务,可以消去耗时最高的一件任务,而不一定是最后一件任务。

代码
class Solution {
public:
    int minTime(vector<int>& time, int m) {
        int l = 0, r = 1 << 30;
        int tiki = 0;
        while (l < r) {
            int x = l + r >> 1;
            int cnt = 1, cur = 0, ma = 0, tot = 1;
            for (int i = 0; i < time.size();) {
                int v = time[i];
                if (cur + v <= x) {
                    cur += v;
                    ma = max(ma, v);
                    i ++;
                } else {
                    if (tot) {
                        if (v > ma) {
                            tot = 0;
                            i ++;
                        } else {
                            tot --;
                            cur -= ma;
                        }
                    } else {
                        cur = 0;
                        ma = 0;
                        tot = 1;
                        cnt ++;
                    }
                }
            }
            if (cnt <= m) r = x;
            else l = x + 1;
        }
        return l;
    }
};