• Leetcode 1494


    并行课程

    给你一个整数 n 表示某所大学里课程的数目,编号为 1 到 n ,数组 dependencies 中, dependencies[i] = [xi, yi]  表示一个先修课的关系,也就是课程 xi 必须在课程 yi 之前上。同时你还有一个整数 k 。

    在一个学期中,你 最多 可以同时上 k 门课,前提是这些课的先修课在之前的学期里已经上过了。

    请你返回上完所有课最少需要多少个学期。题目保证一定存在一种上完所有课的方式。

    思路

    刚开始认为是拓扑排序,但发现对于度相同的情况,先选择哪一个没有正确的贪心方案。因此本题实质上是一个状态压缩dp
    最终的maks=(1<<n)-1,该状态应由可行状态一步步转移而来。什么是可行状态呢?首先是一个状态1的个数不超过k,二是每个状态s中1代表的先修课程不能出现在状态s中。
    此外,每次转移过程,可行状态都是mask的一个子集。于是代码如下:

    class Solution {
    public:
        const int INF=0x3f3f3f3f;
        int minNumberOfSemesters(int n, vector<vector<int>>& dependencies, int k) {
            vector<int>pre(n);
            for(auto dep:dependencies)  //课程y的先修课程
                pre[dep[1]-1]|=(1<<(dep[0]-1));
            vector<int>dp(1<<n,INF),set(1<<n);
            vector<int>valid(1<<n);
            for(int i=0;i<(1<<n);i++)//枚举所有状态
            {
                if(__builtin_popcount(i)<=k){  //寻找可行状态并记录其所有的先修课程
                    for(int j=0;j<n;j++){
                        if(i&(1<<j))  //i中存在状态j
                            set[i]|=pre[j]; //状态i所需要修的所有先修课程
                    }
                    valid[i]=((i&set[i])==0);  //要保证状态i不会和他的先修课程存在重合
                } 
            }
            dp[0]=0;
            for(int mask=0;mask<(1<<n);mask++)
            {
                for(int subset=mask;subset;subset=mask&(subset-1))  //当前正在进行的状态是subset,下一状态是mask,状态由[mask^subset]转移而来,subset状态是mask的子集,for循环体现了一种遍历mask所有子集的过程
                {
                    if(valid[subset]&&((mask&set[subset])==set[subset])){
                        dp[mask]=min(dp[mask],dp[mask^subset]+1);
                    }
                }
            }
            return dp[(1<<n)-1];
        }
    };
    
  • 相关阅读:
    第二篇:后端导出 Excel
    while 循环、for 循环
    <textarea></textarea>多行文本域
    git 基本命令
    如何让div可选中,有聚焦、失焦等事件。
    [leetcode]205. Isomorphic Strings
    [leetcode]204. Count Primes
    Here is a 10-line template that can solve most 'substring' problems子字符串问题的模板
    [leetcode]76. Minimum Window Substring
    [leetcode]166. Fraction to Recurring Decimal
  • 原文地址:https://www.cnblogs.com/flightless/p/13767539.html
Copyright © 2020-2023  润新知