LeetCode 1723. 完成所有工作的最短时间 (状态压缩DP)

1723. 完成所有工作的最短时间
以人数为阶段进行考虑,考虑再多一个人的情况下,根据任务的分配状况 s, 如何进行转移。

如果以任务的分配为阶段进行考虑,最好也就是 O ( n ! ) O(n!) O(n!)的复杂度了。

DP公式:
f [ i ] [ s ] = m i n ( f [ i ] [ s ] , m a x ( f [ i − 1 ] [ j ] , s u m [ s − j ] ) ) ; f[i][s] = min(f[i][s],max(f[i-1][j],sum[s - j])); f[i][s]=min(f[i][s],max(f[i1][j],sum[sj]));

时间复杂度: O ( k ∗ 3 n ) O(k*3^n) O(k3n)

class Solution {

    int low_idx(int x) {
        int idx = 0;
        while((x&1) == 0) {
            idx++;
            x >>= 1;
        }
        return idx;
    }

public: 
    int minimumTimeRequired(vector<int>& jobs, int k) {
        int n = jobs.size();
        int limit = 1<<n;

        vector<vector<int>> f(k+1,vector<int>(limit,(int)1e9));

        // 预处理
        vector<int> sum(limit);

        for(int s = 1; s < limit; s++) {
            int idx = low_idx(s);
            sum[s] = sum[s - (1<<idx)] + jobs[idx];
        }
       	// 初始化 
        f[1] = sum;
       
        for(int i = 2; i <= k; i++) {
            for(int s = 1; s < limit; s++) {
                // f[i][s] = min(max(f[i-1][c],c'));
                // 快速枚举子集
                for(int j = s; j > 0; j = (j-1)&s) {
                    f[i][s] = min(f[i][s],max(f[i-1][j],sum[s - j])); 
                }
            }
        }

        return f[k][limit-1];
    }
};
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值