Skip to content

Commit b8a4e54

Browse files
committed
1494
1 parent 82a281c commit b8a4e54

File tree

5 files changed

+296
-0
lines changed

5 files changed

+296
-0
lines changed

leetcode/1494/0.in

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
5
2+
[[2,1],[3,1],[4,1],[1,5]]
3+
2
4+
5+
00000
6+
00110
7+
00000
8+
00000
9+
01000
10+
11+
0
12+
0
13+
1
14+
1
15+
0

leetcode/1494/comb.cpp

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
/// http://rosettacode.org/wiki/Combinations#C.2B.2B
2+
3+
#include <algorithm>
4+
#include <iostream>
5+
#include <string>
6+
7+
void comb(int N, int K)
8+
{
9+
std::string bitmask(K, 1); // K leading 1's
10+
bitmask.resize(N, 0); // N-K trailing 0's
11+
12+
// print integers and permute bitmask
13+
do {
14+
for (int i = 0; i < N; ++i) // [0..N-1] integers
15+
{
16+
if (bitmask[i]) std::cout << " " << i;
17+
}
18+
std::cout << std::endl;
19+
} while (std::prev_permutation(bitmask.begin(), bitmask.end()));
20+
}
21+
22+
int main()
23+
{
24+
comb(5, 3);
25+
}

leetcode/1494/main.cpp

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
/*
2+
3+
*/
4+
5+
#include <bits/stdc++.h>
6+
#include "../../lib/LeetCodeInput.hpp"
7+
#include "solution-2.cpp"
8+
using namespace std;
9+
10+
int main()
11+
{
12+
LeetCodeInput li("0.in");
13+
14+
vector<vector<int>> mat_1 = li.get_vvi(1);
15+
// vector<int> arr_1 = li.get_vi(0);
16+
int num_1 = li.get_i(0);
17+
int num_2 = li.get_i(2);
18+
// string s_1 = li.get_s(0);
19+
20+
chrono::steady_clock::time_point begin = chrono::steady_clock::now();
21+
Solution solution;
22+
auto output = solution.minNumberOfSemesters(num_1, mat_1, num_2);
23+
chrono::steady_clock::time_point end = chrono::steady_clock::now();
24+
cout << "Time difference = " << chrono::duration_cast<chrono::microseconds> (end - begin).count() << "µs" << endl;
25+
26+
cout << output << endl;
27+
28+
// for (int i: output){
29+
// cout << i << ' ';
30+
// }
31+
32+
// for (auto i: output){
33+
// for (int j: i){
34+
// cout << j << ' ';
35+
// }
36+
// cout << '\n';
37+
// }
38+
39+
return 0;
40+
}

leetcode/1494/solution-2.cpp

Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
/*
2+
3+
time: O()
4+
space: O()
5+
6+
Runtime: 22 ms, faster than 100.00% of C++ online submissions for Parallel Courses II.
7+
Memory Usage: 8.4 MB, less than 88.21% of C++ online submissions for Parallel Courses II.
8+
9+
reference: leetcoe 26ms solution
10+
11+
dfs
12+
*/
13+
14+
#include <bits/stdc++.h>
15+
16+
using namespace std;
17+
18+
#define all(x) begin(x), end(x)
19+
typedef vector<int> vi;
20+
typedef vector<vector<int>> vvi;
21+
22+
class Solution {
23+
public:
24+
int N , K;
25+
26+
vector<vector<int>> graph;
27+
int indegree[15];
28+
int finalBitMask;
29+
int dp[(1 << 15) + 1];
30+
31+
int solve(int bitMask) {
32+
if (bitMask == finalBitMask) return 0;
33+
if (dp[bitMask] != -1) return dp[bitMask];
34+
35+
memset(indegree, 0, sizeof(indegree));
36+
37+
for (int i = 0; i < N; i++) {
38+
if (!(bitMask & (1 << i))) {
39+
for (int v : graph[i]) {
40+
indegree[v]++;
41+
}
42+
}
43+
}
44+
45+
int availMask = 0;
46+
47+
for (int i = 0; i < N; i++) {
48+
if (!(bitMask & (1 << i)) && indegree[i] == 0) availMask |= (1 << i);
49+
}
50+
51+
// before doing this check for the case where number of available courses are <= K
52+
int curAns = N + 1;
53+
if (__builtin_popcount(availMask) < K) {
54+
curAns = min(curAns, 1 + solve(bitMask | availMask));
55+
}
56+
57+
// else if the number of available courses are greater than k, do this
58+
else {
59+
// generating the submasks of a given bitMask
60+
for (int subMask = availMask; subMask > 0; subMask = (subMask - 1) & availMask) {
61+
if (__builtin_popcount(subMask) == K) {
62+
curAns = min(curAns, 1 + solve(bitMask | subMask));
63+
}
64+
}
65+
}
66+
return dp[bitMask] = curAns;
67+
}
68+
69+
int minNumberOfSemesters(int n, vector<vector<int>>& relations, int k) {
70+
N = n;
71+
K = k;
72+
graph.resize(N);
73+
74+
for (auto &e : relations) {
75+
graph[--e[0]].push_back(--e[1]);
76+
}
77+
78+
memset(dp, -1, sizeof(dp));
79+
finalBitMask = ((1 << N) - 1);
80+
return solve(0);
81+
}
82+
};

leetcode/1494/solution.cpp

Lines changed: 134 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,134 @@
1+
/*
2+
3+
time: O()
4+
space: O()
5+
6+
Runtime: 149 ms, faster than 50.41% of C++ online submissions for Parallel Courses II.
7+
Memory Usage: 37.1 MB, less than 17.48% of C++ online submissions for Parallel Courses II.
8+
9+
bfs
10+
*/
11+
12+
#include <bits/stdc++.h>
13+
14+
using namespace std;
15+
16+
#define all(x) begin(x), end(x)
17+
typedef vector<int> vi;
18+
typedef vector<vector<int>> vvi;
19+
20+
typedef int bint;
21+
22+
class Solution {
23+
public:
24+
bint rel[16] = {};
25+
int required[16] = {};
26+
int fulfilled[16];
27+
int k;
28+
int n;
29+
int minNumberOfSemesters(int course_count, vector<vector<int>>& relations, int max_to_take) {
30+
k = max_to_take;
31+
n = course_count;
32+
/// n=2, toTakeNextTerm = 0x...110
33+
// can_take_first_term = (1<<(n+1)) - 2;
34+
for (auto & relation : relations){
35+
rel[relation[1]] |= 1<<relation[0];
36+
++required[relation[1]];
37+
// can_take_first_term &= ~1<<relation[1];
38+
}
39+
40+
vi takens = {0};
41+
bfs(takens);
42+
43+
return term_count;
44+
}
45+
46+
int term_count = 0;
47+
int seen[65536] = {};
48+
void bfs(vi & takens){
49+
vi to_takes;
50+
for (auto & taken : takens){
51+
/// get course can be taken this term according to taken
52+
auto can_take_this_term = get_can_take_this_term(taken);
53+
if (can_take_this_term == 0){
54+
return;
55+
}
56+
/// select k courses from can_take_this_term
57+
auto selects_this_term = get_selects_this_term(can_take_this_term);
58+
for (auto & new_taken : selects_this_term){
59+
int to_take = taken | new_taken;
60+
if (!seen[to_take]){
61+
seen[to_take] = 1;
62+
to_takes.push_back(to_take);
63+
}
64+
}
65+
}
66+
++term_count;
67+
bfs(to_takes);
68+
}
69+
70+
/// O(n2)
71+
inline int get_can_take_this_term(int & taken){
72+
memset(fulfilled+1, 0, 4*n);
73+
bint can_take_this_term = 0;
74+
/// O(n2)
75+
for (int j = 1; j<=n; ++j){
76+
// bint fulfilled_j = rel[j] & taken;
77+
// while (fulfilled_j!=0){
78+
// if (fulfilled_j & 1) ++fulfilled[j];
79+
// fulfilled_j >>= 1;
80+
// }
81+
fulfilled[j] = __builtin_popcount(rel[j] & taken);
82+
}
83+
for (int i=1; i<=n; ++i){
84+
if (fulfilled[i] >= required[i]){
85+
can_take_this_term |= 1<<i;
86+
}
87+
}
88+
can_take_this_term &= ~taken;
89+
return can_take_this_term;
90+
}
91+
92+
inline vi get_selects_this_term(int & can_take_this_term){
93+
// int cnt_can_take_this_term = 0;
94+
// int tmp = can_take_this_term;
95+
// while (tmp!=0){
96+
// if (tmp & 1) ++cnt_can_take_this_term;
97+
// tmp >>= 1;
98+
// }
99+
// if (cnt_can_take_this_term<=k) return {can_take_this_term};
100+
if (__builtin_popcount(can_take_this_term)<=k) return {can_take_this_term};
101+
102+
vi pos_1;
103+
pos_1.reserve(n);
104+
for (int i=0; can_take_this_term!=0; ++i){
105+
if (can_take_this_term & 1) pos_1.push_back(i);
106+
can_take_this_term >>= 1;
107+
}
108+
int N = pos_1.size();
109+
110+
string bitmask(k, 1);
111+
bitmask.resize(N, 0);
112+
113+
vi res;
114+
do {
115+
int select = 0;
116+
for (int i = 0; i < N; ++i) // [0..N-1] integers
117+
{
118+
if (bitmask[i]) {
119+
select |= 1<<pos_1[i];
120+
}
121+
}
122+
res.push_back(select);
123+
} while (std::prev_permutation(bitmask.begin(), bitmask.end()));
124+
125+
return res;
126+
}
127+
};
128+
129+
const static auto initialize = [] {
130+
std::ios::sync_with_stdio(false);
131+
std::cin.tie(nullptr);
132+
std::cout.tie(nullptr);
133+
return nullptr;
134+
}();

0 commit comments

Comments
 (0)