模板题目
题目
思路1————贪心
- 这个就是上面题目的升级版,区间选点不再是一个,而是每个区间需要至少选一定数量的点
- 同理,我们只需要用一个run数组来记录那些时间是被使用过的,然后从后往前补上确实的运行时间即可
代码
class Solution {
public:
int findMinimumTime(vector<vector<int>>& tasks) {
sort(tasks.begin(),tasks.end(),[&](vector<int> &a,vector<int> &b)
{
return a[1] < b[1];
});
int run[2023] = {0};
int ans = 0;
for(auto task:tasks)
{
int l = task[0],r = task[1],ti = task[2];
int has_run = 0;
for(int i = l;i <= r;i ++)
{
has_run += run[i];
}
if(has_run >= ti)continue;
for(int i = r;i >= l;i --)if(ti > has_run)
{
if(!run[i])
{
has_run ++;
run[i] = 1;
ans ++;
}
}
}
return ans;
}
};
思路2————贪心+线段树
- 贪心思路和上面一样
- 只不过用上了线段树的区间修改
- 优先修改右子树
- 找到从未更新过的子线段,然后判断是否数量足够、是否已满、是否被用过,然后再更新答案
- 带入的更新value可以用引用
- 然后返回,判断value > 0
代码
class Solution {
typedef long long LL;
const static int N = 2100;
struct Node
{
int l, r;
LL sum, add;
}tr[N * 4];
void pushup(int u)
{
tr[u].sum = tr[u << 1].sum + tr[u << 1 | 1].sum;
}
void pushdown(int u)
{
auto &root = tr[u], &left = tr[u << 1], &right = tr[u << 1 | 1];
if (root.add)
{
left.add = root.add, left.sum = (LL) (left.r - left.l + 1) * root.add;
right.add = root.add, right.sum = (LL) (right.r - right.l + 1) * root.add;
root.add = 0;
}
}
void build(int u, int l, int r)
{
if (l == r) tr[u] = {l, r, 0, 0};
else
{
tr[u] = {l, r};
int mid = l + r >> 1;
build(u << 1, l, mid), build(u << 1 | 1, mid + 1, r);
pushup(u);
}
}
void modify(int u, int l, int r, int &v)
{
if(tr[u].sum == tr[u].r - tr[u].l + 1)return ;
if (l <= tr[u].l && tr[u].r <= r && tr[u].sum == 0 && tr[u].r - tr[u].l + 1 <= v)
{
v -= tr[u].r - tr[u].l + 1;
tr[u].sum = (tr[u].r - tr[u].l + 1);
tr[u].add = 1;
}
else
{
pushdown(u);
int mid = tr[u].l + tr[u].r >> 1;
if (r > mid && v > 0) modify(u << 1 | 1, l, r, v);
if (l <= mid && v > 0) modify(u << 1, l, r, v);
pushup(u);
}
}
LL query(int u, int l, int r)
{
if (l <= tr[u].l && tr[u].r <= r) return tr[u].sum;
pushdown(u);
int mid = tr[u].l + tr[u].r >> 1;
LL v = 0;
if (l <= mid) v = query(u << 1, l, r);
if (r > mid) v += query(u << 1 | 1, l, r);
return v;
}
public:
int findMinimumTime(vector<vector<int>>& tasks) {
sort(tasks.begin(),tasks.end(),[&](vector<int> &a,vector<int> &b)
{
return a[1] < b[1];
});
build(1,1,tasks.back()[1]);
for(auto task:tasks)
{
int l = task[0],r = task[1],ti = task[2];
ti -= query(1,l,r);
if(ti > 0)modify(1,l,r,ti);
}
return query(1,1,tasks.back()[1]);
}
};
最后
- 又学到了新的线段树

【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 清华大学推出第四讲使用 DeepSeek + DeepResearch 让科研像聊天一样简单!
· 推荐几款开源且免费的 .NET MAUI 组件库
· 实操Deepseek接入个人知识库
· 易语言 —— 开山篇
· Trae初体验