leetcode

Leetcode Solutions (0x6A73)
git clone https://git.pngu.org/leetcode
Log | Files | Refs | Submodules | README

commit dac10095fd54f29edb2e262a408a515de725a0e8
parent 387b3ecf24e20ffaaafcf111654b04e14ffd7704
Author: Jack Sangdahl <jack@pngu.org>
Date:   Mon, 29 Dec 2025 20:17:35 -0700

1494. parallel courses 2

Diffstat:
Aparallel_courses2.c | 67+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Aparallel_courses2.py | 50++++++++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 117 insertions(+), 0 deletions(-)

diff --git a/parallel_courses2.c b/parallel_courses2.c @@ -0,0 +1,67 @@ +// 1494. Parallel Courses II +#include "leetcode.h" + +/* + * you are given an integer 'n' which indicates that there are 'n' courses + * labeled from 1 to 'n'. you are also given an array 'relations' where + * 'relations[i] = [prev_course[i], next_course[i]]', representing a + * prerequisite relationship between course 'prev_course' and course + * 'next_course': course 'prev_course' has to be taken before 'next_course'. + * also, you are given integer 'k'. in one semester, you can take most 'k' + * course as long as you have taken all the prerequisites in the previous + * semesters for the courses you are taking. return the minimum number of + * semesters needed to take all courses. the testcases will be generated such + * that it is possible to take every course. + */ + +int minNumberOfSemesters(int n, int **relations, int relationsSize, + int *relationsColSize, int k) { + int *dp = (int *)malloc((1 << n) * sizeof(int)); + int *prereq = (int *)calloc(1 << n, sizeof(int)); + int *pre_course = (int *)malloc(n); + for (int i = 0; i < (1 << n); i++) + dp[i] = INT_MAX / 2; + for (int i = 0; i < relationsSize; i++) { + int u = relations[i][0] - 1; + int v = relations[i][1] - 1; + pre_course[v] |= (1 << u); + } + for (int i = 0; i < (1 << n); i++) { + for (int j = 0; j < n; j++) + if ((i >> j) & 1) + prereq[i] |= pre_course[j]; + if (!prereq[i] && __builtin_popcount(i) <= k) + dp[i] = 1; + } + dp[0] = 0; + for (int i = 0; i < (1 << n); i++) { + int x = __builtin_popcount(i); + for (int j = i; j > 0; j = ((j - 1) & j)) { + int y = __builtin_popcount(j); + if (x - y > k) + continue; + if ((prereq[i] & j) == prereq[i]) + dp[i] = fmin(dp[i], dp[j] + 1); + } + } + int ans = (dp[(1 << n) - 1] == INT_MAX / 2) ? -1 : dp[(1 << n) - 1]; + free(dp); + free(prereq); + free(pre_course); + return ans; +} + +int main() { + int r1i[3][2] = {{2, 1}, {3, 1}, {1, 4}}; + int r2i[4][2] = {{2, 1}, {3, 1}, {4, 1}, {1, 5}}; + struct two_d_arr *r1 = + two_d_arr_init(ARRAY_SIZE(r1i), ARRAY_SIZE(r1i[0]), r1i); + struct two_d_arr *r2 = + two_d_arr_init(ARRAY_SIZE(r2i), ARRAY_SIZE(r2i[0]), r2i); + printf("%d\n", minNumberOfSemesters(4, r1->arr, r1->row_size, r1->col_size, + 2)); // expect: 3 + printf("%d\n", minNumberOfSemesters(5, r2->arr, r2->row_size, r2->col_size, + 2)); // expect: 4 + two_d_arr_free(r1); + two_d_arr_free(r2); +} diff --git a/parallel_courses2.py b/parallel_courses2.py @@ -0,0 +1,50 @@ +# 1494. Parallel Courses II +from itertools import permutations + +""" +you are given an integer 'n' which indicates that there are 'n' courses +labeled from 1 to 'n'. you are also given an array 'relations' where +'relations[i] = [prev_course[i], next_course[i]]', representing a +prerequisite relationship between course 'prev_course' and course +'next_course': course 'prev_course' has to be taken before 'next_course'. +also, you are given integer 'k'. in one semester, you can take most 'k' +course as long as you have taken all the prerequisites in the previous +semesters for the courses you are taking. return the minimum number of +semesters needed to take all courses. the testcases will be generated such +that it is possible to take every course. +""" + + +class Solution(object): + def minNumberOfSemesters(self, n, relations, k): + """ + :type n: int + :type relations: List[List[int]] + :type k: int + :rtype: int + """ + dp = [[(100, 0, 0)] * n for _ in range(1 << n)] + prereq = [0] * n + for i, j in relations: + prereq[j - 1] ^= 1 << (i - 1) + for i in range(n): + if prereq[i] == 0: + dp[1 << i][i] = (1, 1, 1 << i) + for i in range(1 << n): + nz_bit = [len(bin(i)) - j - 1 for j, l in enumerate(bin(i)) if l == "1"] + for j, l in permutations(nz_bit, 2): + if prereq[l] & i == prereq[l]: + candid, bits, mask = dp[i ^ (1 << l)][j] + if prereq[l] & mask == 0 and bits < k: + dp[i][l] = min(dp[i][l], (candid, bits + 1, mask + (1 << l))) + else: + dp[i][l] = min(dp[i][l], (candid + 1, 1, 1 << l)) + return min([i for i, j, k in dp[-1]]) + + +if __name__ == "__main__": + obj = Solution() + print(obj.minNumberOfSemesters(n=4, relations=[[2, 1], [3, 1], [1, 4]], k=2)) + print( + obj.minNumberOfSemesters(n=5, relations=[[2, 1], [3, 1], [4, 1], [1, 5]], k=2) + )