1494.并行课程II
链接:1494.并行课程II
难度:Hard
标签:位运算、图、动态规划、状态压缩
简介:给你一个整数 n 表示某所大学里课程的数目,编号为 1 到 n ,数组 relations 中, relations[i] = [xi, yi] 表示一个先修课的关系,也就是课程 xi 必须在课程 yi 之前上。同时你还有一个整数 k 。在一个学期中,你 最多 可以同时上 k 门课,前提是这些课的先修课在之前的学期里已经上过了。请你返回上完所有课最少需要多少个学期。
题解 1 - cpp
- 编辑时间:2023-06-16
- 执行用时:680ms
- 内存消耗:168.4MB
- 编程语言:cpp
- 解法介绍:dfs遍历,判断同一期每个点上课的情况。
#define SIZE 13
struct Node {
int idx, child_cnt;
unordered_set<int> parents, children;
};
class Solution {
public:
int minNumberOfSemesters(int n, vector<vector<int>>& relations, int k) {
vector<Node> list(n);
for (int i = 0; i < n; i++) {
list[i].idx = i;
list[i].child_cnt = 0;
}
for (auto &item : relations) {
list[item[1] - 1].parents.insert(item[0] - 1);
list[item[0] - 1].children.insert(item[1] - 1);
}
// for (int i = 0; i < n; i++) {
// cout << "i = " << i
// << ", parent = ";
// for (auto &p : list[i].parents) cout << p << ", ";
// cout << ", children = ";
// for (auto &c : list[i].children) cout << c << ", ";
// cout << endl;
// }
int empty = 0, res = INT_MAX;
for (int i = 0; i < n; i++) {
if (list[i].parents.size() == 0) empty |= 1 << i;
}
unordered_map<int, unordered_map<int, unordered_map<int, unordered_map<int, int>>>> cache;
function<int(int, int, int, int)> dfs = [&](int empty, int used, int cur_res, int cur_k){
if (cache[empty][used][cur_res][cur_k]) return cache[empty][used][cur_res][cur_k];
// cout << "dfs "
// << ", empty = " << bitset<SIZE>(empty).to_string()
// << ", used = " << bitset<SIZE>(used).to_string()
// << ", cur_res = " << cur_res
// << ", cur_k = " << cur_k
// << endl;
if (used == (1 << n) - 1) {
if (cur_k) cur_res += 1;
return cache[empty][used][cur_res][cur_k] = cur_res;
}
if (cur_k == k || empty == 0) {
int next_empty = empty;
for (int i = 0; i < n; i++) {
if ((used & (1 << i)) == 0 && list[i].parents.size() == 0) next_empty |= 1 << i;
}
return cache[empty][used][cur_res][cur_k] = dfs(next_empty, used, cur_res + 1, 0);
}
int res = INT_MAX;
for (int i = 0; i < n; i++) {
if (empty & (1 << i)) {
for (auto &c : list[i].children) list[c].parents.erase(i);
res = min(res, dfs(empty & ~(1 << i), used | (1 << i), cur_res, cur_k + 1));
for (auto &c : list[i].children) list[c].parents.insert(i);
}
}
return cache[empty][used][cur_res][cur_k] = res;
};
return dfs(empty, 0, 0, 0);
}
};