[Hdfs] lc1723. 完成所有工作的最短时间(dfs+状压dp+周赛223_4)

33 篇文章 3 订阅
本文探讨了一道关于将n个任务分配给k个工人的最短时间问题,通过状态压缩动态规划方法求解,并强调了剪枝优化在避免超时上的关键作用。作者通过示例代码展示了如何使用dfs进行遍历,以及如何通过检查当前最大值来决定是否继续搜索。
摘要由CSDN通过智能技术生成

1. 题目来源

链接:1723. 完成所有工作的最短时间

2. 题目解析

本题正解应该是状压 dp,但由于好久好久没弄困难的 dp 问题了,手太生。这个 n 又这么小,还是暴搜会比较香。
在这里插入图片描述
每个数两种情况,要么加到现有组中,要么自成一组。也快到临界值了,得加上剪枝优化,dfs() 参数存一个最大值,不要自己循环求最大值这妥妥超时,也不要用 min() 来更新最大值,这样就不是剪枝了。当传递的参数最大值还没全局最大值小的时候,后面的情况都不需要再考虑了,直接 return 即可,加上剪枝优化后速度直接飞起。


  • 时间复杂度 O ( 不 会 分 析 ) O(不会分析) O()
  • 空间复杂度 O ( 不 会 分 析 ) O(不会分析) O()

代码:

class Solution {
public:
    vector<int> jobs;                       // 全局数据,方便传参
    vector<int> s;                          // 集合,分配给 k 个工人,每个工人分配的工作总时间
    int res = 1e9;                          // 全局最大值

    // 需要记录最大值,不能循环来求,否则时间复杂度会变成 10^7,超时
    void dfs(int a, int b, int c) {         // 枚举到第a项工作,当前有b组,当前方案的最大时间为c
        if (c > res) return ;    // 这个优化很重要,如果当前最大工作时间已经大于全局的 res, 则可以直接 return 当前部分做剪枝
        if (a == jobs.size()) {
            res = c;
            return ;
        }

        for (int i = 0; i < b; i ++ ) {     // 分到现有组中
            s[i] += jobs[a];
            dfs(a + 1, b, max(c, s[i]));
            s[i] -= jobs[a];                // 恢复现场
        }

        if (b < s.size()) {                 // 自成新组,但不能超过限制组数
            s[b] = jobs[a];
            dfs(a + 1, b + 1, max(c, s[b]));
            s[b] = 0;
        }
    }

    // n 个任务分成 k 个不同的非空子集,斯特林数,大约是 130w 计算量,可以直接暴搜
    int minimumTimeRequired(vector<int>& _jobs, int k) {
        jobs = _jobs;
        s.resize(k);            // 最多分 k 组,分给 k 个工人
        dfs(0, 0, 0);
        return res;
    }
};
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Ypuyu

如果帮助到你,可以请作者喝水~

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值