├── Module 12 ├── .gitignore ├── divide.cpp ├── merge.cpp └── merge_sort.cpp ├── Module 13 ├── .gitignore ├── adjacency_list.cpp ├── adjacency_matrix.cpp ├── bfs.cpp ├── dfs.cpp └── edge_list.cpp ├── Module 14 ├── .gitignore ├── bfs_path.cpp ├── dijkstra_naive.cpp └── dijkstra_optimized.cpp ├── Module 15 ├── .gitignore ├── Building_Roads.cpp ├── Counting_Rooms.cpp ├── bfs_2d.cpp ├── components.cpp ├── flood_fill.cpp └── max_area_of_island.cpp ├── Module 17 ├── .gitignore ├── belllman_ford.cpp ├── check_negative_cycle.cpp └── floyd_warshell.cpp ├── Module 18 ├── .gitignore ├── Building_Roads.cpp ├── Road_Construction.cpp ├── find.cpp ├── undirected_cycle_detect.cpp ├── union.cpp ├── union_by_rank.cpp └── union_by_size.cpp ├── Module 19 ├── .gitignore ├── Road_Reparation.cpp ├── Road_Reparation_Kruskal.cpp ├── kruskal_mst.cpp └── prims_mst.cpp ├── Module 21 ├── .gitignore ├── A_Frog_1.cpp ├── A_Frog_1_Top_Down.cpp ├── fibonacci_loop.cpp ├── fibonacci_memoization.cpp └── fibonacci_recursion.cpp ├── Module 22 ├── .gitignore ├── 0-1_knapsack_bottom_up.cpp ├── 0-1_knapsack_memoization.cpp ├── 0-1_knapsack_recursion.cpp ├── U_Knapsack.cpp └── knapsack-geeksforgeeks.cpp ├── Module 23 ├── .gitignore ├── count_of_subset_sum.cpp ├── equal_sum.cpp ├── minimum_subset_sum_difference.cpp ├── subset_sum_bottom_up.cpp └── subset_sum_top_down.cpp ├── Module 25 ├── .gitignore ├── coin_change_1.cpp ├── coin_change_2.cpp ├── rod_cutting.cpp ├── unbounded_knapsack.cpp └── unbounded_knapsack_bottom_up.cpp ├── Module 26 ├── .gitignore ├── lcs_bottom_up.cpp ├── lcs_print.cpp ├── lcs_top_down.cpp └── longest_common_substring.cpp └── Module 27 ├── .gitignore ├── check_string_a_is_subsequence.cpp ├── print_lps.cpp ├── print_shortest_common_supersequence.cpp └── shortest_common_supersequence.cpp /Module 12/.gitignore: -------------------------------------------------------------------------------- 1 | .cph/ 2 | .vscode/ 3 | *.txt 4 | *.exe 5 | *.bin -------------------------------------------------------------------------------- /Module 12/divide.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | void divide(int a[],int l, int r) 4 | { 5 | for(int i=l;i<=r;i++) 6 | { 7 | cout<>n; 21 | int a[n]; 22 | for(int i=0;i>a[i]; 25 | } 26 | divide(a,0,n-1); 27 | return 0; 28 | } -------------------------------------------------------------------------------- /Module 12/merge.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | void merge(int a[],int l,int m,int r) 4 | { 5 | int leftSize = m-l+1; 6 | int rightSize = r-m; 7 | int L[leftSize],R[rightSize]; 8 | int k=0; 9 | for(int i=l;i<=m;i++) 10 | { 11 | L[k]=a[i]; 12 | k++; 13 | } 14 | k=0; 15 | for(int i=m+1;i<=r;i++) 16 | { 17 | R[k]=a[i]; 18 | k++; 19 | } 20 | int i=0,j=0; 21 | int cur=l; 22 | while(i>n; 55 | int a[n]; 56 | for(int i=0;i>a[i]; 59 | } 60 | merge(a,0,3,n-1); 61 | for(int i=0;i 2 | using namespace std; 3 | void merge(int a[],int l,int m,int r) 4 | { 5 | int leftSize = m-l+1; 6 | int rightSize = r-m; 7 | int L[leftSize],R[rightSize]; 8 | int k=0; 9 | for(int i=l;i<=m;i++) 10 | { 11 | L[k]=a[i]; 12 | k++; 13 | } 14 | k=0; 15 | for(int i=m+1;i<=r;i++) 16 | { 17 | R[k]=a[i]; 18 | k++; 19 | } 20 | int i=0,j=0; 21 | int cur=l; 22 | while(i>n; 77 | int a[n]; 78 | for(int i=0;i>a[i]; 81 | } 82 | merge_sort(a,0,n-1); 83 | // for(int i=0;i 2 | using namespace std; 3 | int main() 4 | { 5 | int n, e; 6 | cin >> n >> e; 7 | vector adj[n + 1]; 8 | while (e--) 9 | { 10 | int a, b; 11 | cin >> a >> b; 12 | adj[a].push_back(b); 13 | adj[b].push_back(a); 14 | } 15 | for (int i = 0; i <= n; i++) 16 | { 17 | cout << "Index " << i << ": "; 18 | for (int j = 0; j < adj[i].size(); j++) 19 | { 20 | cout << adj[i][j] << " "; 21 | } 22 | cout << endl; 23 | } 24 | return 0; 25 | } -------------------------------------------------------------------------------- /Module 13/adjacency_matrix.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | int main() 4 | { 5 | int n, e; 6 | cin >> n >> e; 7 | int adj[n + 1][n + 1]; 8 | for (int i = 0; i <= n; i++) 9 | { 10 | for (int j = 0; j <= n; j++) 11 | { 12 | adj[i][j] = 0; 13 | if (i == j) 14 | adj[i][j] = 1; 15 | } 16 | } 17 | 18 | while (e--) 19 | { 20 | int a, b; 21 | cin >> a >> b; 22 | adj[a][b] = 1; 23 | adj[b][a] = 1; 24 | } 25 | for (int i = 0; i <= n; i++) 26 | { 27 | for (int j = 0; j <= n; j++) 28 | { 29 | cout << adj[i][j] << " "; 30 | } 31 | cout << endl; 32 | } 33 | return 0; 34 | } -------------------------------------------------------------------------------- /Module 13/bfs.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | const int N = 1e5 + 5; 4 | int dis[N]; 5 | bool vis[N]; 6 | vector v[N]; 7 | void bfs(int src) 8 | { 9 | queue q; 10 | q.push(src); 11 | vis[src] = true; 12 | dis[src] = 0; 13 | 14 | while (!q.empty()) 15 | { 16 | int parent = q.front(); 17 | q.pop(); 18 | cout << parent << endl; 19 | for (int i = 0; i < v[parent].size(); i++) 20 | { 21 | int child = v[parent][i]; 22 | if (vis[child] == false) 23 | { 24 | q.push(child); 25 | dis[child] = dis[parent] + 1; 26 | vis[child] = true; 27 | } 28 | } 29 | } 30 | } 31 | int main() 32 | { 33 | int n, e; 34 | cin >> n >> e; 35 | while (e--) 36 | { 37 | int a, b; 38 | cin >> a >> b; 39 | v[a].push_back(b); 40 | v[b].push_back(a); 41 | } 42 | bfs(1); 43 | for (int i = 1; i <= n; i++) 44 | { 45 | cout << "Node " << i << ": " << dis[i] << endl; 46 | } 47 | return 0; 48 | } -------------------------------------------------------------------------------- /Module 13/dfs.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | const int N = 1e5 + 5; 4 | bool vis[N]; 5 | vector v[N]; 6 | void dfs(int s) 7 | { 8 | vis[s] = true; 9 | cout << s << endl; 10 | for (int i = 0; i < v[s].size(); i++) 11 | { 12 | int child = v[s][i]; 13 | if (vis[child] == false) 14 | { 15 | dfs(child); 16 | } 17 | } 18 | } 19 | int main() 20 | { 21 | int n, e; 22 | cin >> n >> e; 23 | while (e--) 24 | { 25 | int a, b; 26 | cin >> a >> b; 27 | v[a].push_back(b); 28 | v[b].push_back(a); 29 | } 30 | dfs(1); 31 | return 0; 32 | } -------------------------------------------------------------------------------- /Module 13/edge_list.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | int main() 4 | { 5 | int n, e; 6 | cin >> n >> e; 7 | vector> v; 8 | while (e--) 9 | { 10 | int a, b; 11 | cin >> a >> b; 12 | v.push_back({a, b}); 13 | } 14 | for (int i = 0; i < v.size(); i++) 15 | { 16 | cout << v[i].first << " " << v[i].second << endl; 17 | } 18 | return 0; 19 | } -------------------------------------------------------------------------------- /Module 14/.gitignore: -------------------------------------------------------------------------------- 1 | .cph/ 2 | .vscode/ 3 | *.txt 4 | *.exe 5 | *.bin -------------------------------------------------------------------------------- /Module 14/bfs_path.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | const int N = 1e5 + 5; 4 | int dis[N]; 5 | bool vis[N]; 6 | int par[N]; 7 | vector v[N]; 8 | void bfs(int s) 9 | { 10 | queue q; 11 | q.push(s); 12 | dis[s] = 0; 13 | par[s] = -1; 14 | vis[s] = true; 15 | while (!q.empty()) 16 | { 17 | int parent = q.front(); 18 | q.pop(); 19 | for (int child : v[parent]) 20 | { 21 | if (!vis[child]) 22 | { 23 | q.push(child); 24 | par[child] = parent; 25 | dis[child] = dis[parent] + 1; 26 | vis[child] = true; 27 | } 28 | } 29 | } 30 | } 31 | int main() 32 | { 33 | int n, e; 34 | cin >> n >> e; 35 | while (e--) 36 | { 37 | int a, b; 38 | cin >> a >> b; 39 | v[a].push_back(b); 40 | v[b].push_back(a); 41 | } 42 | bfs(1); 43 | // for (int i = 1; i <= n; i++) 44 | // { 45 | // cout << "Node " << i << ": " << par[i] << endl; 46 | // } 47 | int d; 48 | cin >> d; 49 | 50 | if (vis[d]) 51 | { 52 | vector path; 53 | int x = d; 54 | while (x != -1) 55 | { 56 | // cout << x << endl; 57 | path.push_back(x); 58 | x = par[x]; 59 | } 60 | reverse(path.begin(), path.end()); 61 | for (int val : path) 62 | { 63 | cout << val << " "; 64 | } 65 | } 66 | else 67 | { 68 | cout << "Path nai" << endl; 69 | } 70 | return 0; 71 | } -------------------------------------------------------------------------------- /Module 14/dijkstra_naive.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | const int N = 1e5 + 5; 4 | vector> v[N]; 5 | int dis[N]; 6 | void dijkstra(int s) 7 | { 8 | queue q; 9 | q.push(s); 10 | dis[s] = 0; 11 | while (!q.empty()) 12 | { 13 | int parent = q.front(); 14 | q.pop(); 15 | for (int i = 0; i < v[parent].size(); i++) 16 | { 17 | pair child = v[parent][i]; 18 | int childNode = child.first; 19 | int childCost = child.second; 20 | if (dis[parent] + childCost < dis[childNode]) 21 | { 22 | dis[childNode] = dis[parent] + childCost; 23 | q.push(childNode); 24 | } 25 | } 26 | } 27 | } 28 | int main() 29 | { 30 | int n, e; 31 | cin >> n >> e; 32 | while (e--) 33 | { 34 | int a, b, w; 35 | cin >> a >> b >> w; 36 | v[a].push_back({b, w}); 37 | v[b].push_back({a, w}); 38 | } 39 | for (int i = 1; i <= n; i++) 40 | { 41 | dis[i] = INT_MAX; 42 | } 43 | dijkstra(1); 44 | for (int i = 1; i <= n; i++) 45 | { 46 | cout << "Node " << i << ": " << dis[i] << endl; 47 | } 48 | return 0; 49 | } -------------------------------------------------------------------------------- /Module 14/dijkstra_optimized.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | const int N = 1e5 + 5; 4 | vector> v[N]; 5 | int dis[N]; 6 | bool vis[N]; 7 | void dijkstra(int s) 8 | { 9 | priority_queue, vector>, greater>> pq; 10 | 11 | pq.push({0, s}); 12 | dis[s] = 0; 13 | while (!pq.empty()) 14 | { 15 | pair parent = pq.top(); 16 | pq.pop(); 17 | int parentNode = parent.second; 18 | if (vis[parentNode]) 19 | { 20 | continue; 21 | } 22 | vis[parentNode] = true; 23 | int parentCost = parent.first; 24 | for (int i = 0; i < v[parentNode].size(); i++) 25 | { 26 | pair child = v[parentNode][i]; 27 | int childNode = child.first; 28 | int childCost = child.second; 29 | if (parentCost + childCost < dis[childNode]) 30 | { 31 | dis[childNode] = parentCost + childCost; 32 | pq.push({dis[childNode], childNode}); 33 | } 34 | } 35 | } 36 | } 37 | int main() 38 | { 39 | int n, e; 40 | cin >> n >> e; 41 | while (e--) 42 | { 43 | int a, b, w; 44 | cin >> a >> b >> w; 45 | v[a].push_back({b, w}); 46 | // v[b].push_back({a, w}); 47 | } 48 | for (int i = 1; i <= n; i++) 49 | { 50 | dis[i] = INT_MAX; 51 | } 52 | dijkstra(1); 53 | for (int i = 1; i <= n; i++) 54 | { 55 | cout << "Node " << i << ": " << dis[i] << endl; 56 | } 57 | return 0; 58 | } -------------------------------------------------------------------------------- /Module 15/.gitignore: -------------------------------------------------------------------------------- 1 | .cph/ 2 | .vscode/ 3 | *.txt 4 | *.exe 5 | *.bin -------------------------------------------------------------------------------- /Module 15/Building_Roads.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | const int N = 1e5 + 5; 4 | int dis[N]; 5 | bool vis[N]; 6 | vector v[N]; 7 | vector cmp; 8 | void dfs(int s) 9 | { 10 | vis[s] = true; 11 | cmp.push_back(s); 12 | for (int child : v[s]) 13 | { 14 | if (!vis[child]) 15 | { 16 | dfs(child); 17 | } 18 | } 19 | } 20 | int main() 21 | { 22 | int n, e; 23 | cin >> n >> e; 24 | while (e--) 25 | { 26 | int a, b; 27 | cin >> a >> b; 28 | v[a].push_back(b); 29 | v[b].push_back(a); 30 | } 31 | vector ans; 32 | for (int i = 1; i <= n; i++) 33 | { 34 | if (!vis[i]) 35 | { 36 | dfs(i); 37 | ans.push_back(i); 38 | } 39 | } 40 | cout << ans.size() - 1 << endl; 41 | for (int i = 0; i < ans.size() - 1; i++) 42 | { 43 | cout << ans[i] << " " << ans[i + 1] << endl; 44 | } 45 | return 0; 46 | } -------------------------------------------------------------------------------- /Module 15/Counting_Rooms.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #define pi pair 3 | using namespace std; 4 | int n, m; 5 | const int N = 1005; 6 | bool vis[N][N]; 7 | char a[N][N]; 8 | vector path = {{-1, 0}, {1, 0}, {0, -1}, {0, 1}}; 9 | bool isValid(int cI, int cJ) 10 | { 11 | if (cI >= 0 && cI < n && cJ >= 0 && cJ < m && a[cI][cJ] == '.') 12 | return true; 13 | else 14 | return false; 15 | } 16 | void dfs(int si, int sj) 17 | { 18 | vis[si][sj] = true; 19 | for (int i = 0; i < 4; i++) 20 | { 21 | pi p = path[i]; 22 | int ci = si + p.first; 23 | int cj = sj + p.second; 24 | if (isValid(ci, cj) && !vis[ci][cj]) 25 | { 26 | dfs(ci, cj); 27 | } 28 | } 29 | } 30 | int main() 31 | { 32 | cin >> n >> m; 33 | for (int i = 0; i < n; i++) 34 | { 35 | for (int j = 0; j < m; j++) 36 | { 37 | cin >> a[i][j]; 38 | } 39 | } 40 | int cnt = 0; 41 | for (int i = 0; i < n; i++) 42 | { 43 | for (int j = 0; j < m; j++) 44 | { 45 | if (!vis[i][j] && a[i][j] == '.') 46 | { 47 | cnt++; 48 | dfs(i, j); 49 | } 50 | } 51 | } 52 | cout << cnt << endl; 53 | return 0; 54 | } -------------------------------------------------------------------------------- /Module 15/bfs_2d.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #define pi pair 3 | using namespace std; 4 | const int N = 1005; 5 | bool vis[N][N]; 6 | int dis[N][N]; 7 | int n, m; 8 | vector path = {{-1, 0}, {1, 0}, {0, -1}, {0, 1}}; 9 | bool isValid(int cI, int cJ) 10 | { 11 | if (cI >= 0 && cI < n && cJ >= 0 && cJ < m) 12 | return true; 13 | else 14 | return false; 15 | } 16 | void bfs(int si, int sj) 17 | { 18 | queue q; 19 | q.push({si, sj}); 20 | dis[si][sj] = 0; 21 | vis[si][sj] = true; 22 | while (!q.empty()) 23 | { 24 | pi parent = q.front(); 25 | int pI = parent.first; 26 | int pJ = parent.second; 27 | q.pop(); 28 | for (int i = 0; i < 4; i++) 29 | { 30 | pi p = path[i]; 31 | int cI = pI + p.first; 32 | int cJ = pJ + p.second; 33 | if (isValid(cI, cJ) && !vis[cI][cJ]) 34 | { 35 | vis[cI][cJ] = true; 36 | q.push({cI, cJ}); 37 | dis[cI][cJ] = dis[pI][pJ] + 1; 38 | } 39 | } 40 | } 41 | } 42 | int main() 43 | { 44 | cin >> n >> m; 45 | char a[n][m]; 46 | for (int i = 0; i < n; i++) 47 | { 48 | for (int j = 0; j < m; j++) 49 | { 50 | cin >> a[i][j]; 51 | } 52 | } 53 | int si, sj; 54 | cin >> si >> sj; 55 | bfs(si, sj); 56 | for (int i = 0; i < n; i++) 57 | { 58 | for (int j = 0; j < m; j++) 59 | { 60 | cout << dis[i][j] << " "; 61 | } 62 | cout << endl; 63 | } 64 | return 0; 65 | } -------------------------------------------------------------------------------- /Module 15/components.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | const int N = 1e5 + 5; 4 | int dis[N]; 5 | bool vis[N]; 6 | vector v[N]; 7 | vector cmp; 8 | void dfs(int s) 9 | { 10 | vis[s] = true; 11 | cmp.push_back(s); 12 | for (int child : v[s]) 13 | { 14 | if (!vis[child]) 15 | { 16 | dfs(child); 17 | } 18 | } 19 | } 20 | int main() 21 | { 22 | int n, e; 23 | cin >> n >> e; 24 | while (e--) 25 | { 26 | int a, b; 27 | cin >> a >> b; 28 | v[a].push_back(b); 29 | v[b].push_back(a); 30 | } 31 | int cnt = 0; 32 | for (int i = 1; i <= n; i++) 33 | { 34 | if (!vis[i]) 35 | { 36 | cnt++; 37 | dfs(i); 38 | for (int val : cmp) 39 | { 40 | cout << val << " "; 41 | } 42 | cout << endl; 43 | cmp.clear(); 44 | } 45 | } 46 | cout << cnt << endl; 47 | return 0; 48 | } -------------------------------------------------------------------------------- /Module 15/flood_fill.cpp: -------------------------------------------------------------------------------- 1 | class Solution 2 | { 3 | public: 4 | bool vis[100][100]; 5 | int n, m; 6 | vector> path = {{-1, 0}, {1, 0}, {0, -1}, {0, 1}}; 7 | bool isValid(int cI, int cJ) 8 | { 9 | if (cI >= 0 && cI < n && cJ >= 0 && cJ < m) 10 | return true; 11 | else 12 | return false; 13 | } 14 | void dfs(int si, int sj, int scolor, int clr, vector> &image) 15 | { 16 | vis[si][sj] = true; 17 | if (image[si][sj] == scolor) 18 | { 19 | image[si][sj] = clr; 20 | } 21 | for (int i = 0; i < 4; i++) 22 | { 23 | pair p = path[i]; 24 | int ci = si + p.first; 25 | int cj = sj + p.second; 26 | if (isValid(ci, cj) && !vis[ci][cj] && image[ci][cj] == scolor) 27 | { 28 | dfs(ci, cj, scolor, clr, image); 29 | } 30 | } 31 | } 32 | vector> floodFill(vector> &image, int sr, int sc, int color) 33 | { 34 | n = image.size(); 35 | m = image[0].size(); 36 | dfs(sr, sc, image[sr][sc], color, image); 37 | return image; 38 | } 39 | }; -------------------------------------------------------------------------------- /Module 15/max_area_of_island.cpp: -------------------------------------------------------------------------------- 1 | class Solution 2 | { 3 | public: 4 | int n, m; 5 | bool vis[100][100]; 6 | vector> path = {{-1, 0}, {1, 0}, {0, -1}, {0, 1}}; 7 | bool isValid(int cI, int cJ) 8 | { 9 | if (cI >= 0 && cI < n && cJ >= 0 && cJ < m) 10 | return true; 11 | else 12 | return false; 13 | } 14 | int cnt; 15 | void dfs(int si, int sj, vector> &grid) 16 | { 17 | vis[si][sj] = true; 18 | cnt++; 19 | for (int i = 00; i < 4; i++) 20 | { 21 | pair p = path[i]; 22 | int ci = si + p.first; 23 | int cj = sj + p.second; 24 | if (isValid(ci, cj) && !vis[ci][cj] && grid[ci][cj] == 1) 25 | { 26 | dfs(ci, cj, grid); 27 | } 28 | } 29 | } 30 | int maxAreaOfIsland(vector> &grid) 31 | { 32 | n = grid.size(); 33 | m = grid[0].size(); 34 | int mx = 0; 35 | for (int i = 0; i < n; i++) 36 | { 37 | for (int j = 0; j < m; j++) 38 | { 39 | if (!vis[i][j] && grid[i][j] == 1) 40 | { 41 | cnt = 0; 42 | dfs(i, j, grid); 43 | mx = max(cnt, mx); 44 | } 45 | } 46 | } 47 | return mx; 48 | } 49 | }; -------------------------------------------------------------------------------- /Module 17/.gitignore: -------------------------------------------------------------------------------- 1 | .cph/ 2 | .vscode/ 3 | *.txt 4 | *.exe 5 | *.bin -------------------------------------------------------------------------------- /Module 17/belllman_ford.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | class Edge 4 | { 5 | public: 6 | int u; 7 | int v; 8 | int w; 9 | Edge(int u, int v, int w) 10 | { 11 | this->u = u; 12 | this->v = v; 13 | this->w = w; 14 | } 15 | }; 16 | int main() 17 | { 18 | int n, e; 19 | cin >> n >> e; 20 | vector v; 21 | while (e--) 22 | { 23 | int a, b, w; 24 | cin >> a >> b >> w; 25 | Edge ed(a, b, w); 26 | v.push_back(ed); 27 | } 28 | int dis[n + 1]; 29 | for (int i = 1; i <= n; i++) 30 | { 31 | dis[i] = INT_MAX; 32 | } 33 | dis[1] = 0; 34 | for (int i = 1; i <= n - 1; i++) 35 | { 36 | for (int j = 0; j < v.size(); j++) 37 | { 38 | Edge ed = v[j]; 39 | int a = ed.u; 40 | int b = ed.v; 41 | int w = ed.w; 42 | if (dis[a] + w < dis[b]) 43 | { 44 | dis[b] = dis[a] + w; 45 | } 46 | } 47 | } 48 | for (int i = 1; i <= n; i++) 49 | { 50 | cout << "Node " << i << ": " << dis[i] << endl; 51 | } 52 | return 0; 53 | } -------------------------------------------------------------------------------- /Module 17/check_negative_cycle.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | class Edge 4 | { 5 | public: 6 | int u; 7 | int v; 8 | int w; 9 | Edge(int u, int v, int w) 10 | { 11 | this->u = u; 12 | this->v = v; 13 | this->w = w; 14 | } 15 | }; 16 | int main() 17 | { 18 | int n, e; 19 | cin >> n >> e; 20 | vector v; 21 | while (e--) 22 | { 23 | int a, b, w; 24 | cin >> a >> b >> w; 25 | Edge ed(a, b, w); 26 | v.push_back(ed); 27 | } 28 | int dis[n + 1]; 29 | for (int i = 1; i <= n; i++) 30 | { 31 | dis[i] = INT_MAX; 32 | } 33 | dis[1] = 0; 34 | for (int i = 1; i <= n - 1; i++) 35 | { 36 | for (int j = 0; j < v.size(); j++) 37 | { 38 | Edge ed = v[j]; 39 | int a = ed.u; 40 | int b = ed.v; 41 | int w = ed.w; 42 | if (dis[a] + w < dis[b]) 43 | { 44 | dis[b] = dis[a] + w; 45 | } 46 | } 47 | } 48 | bool cycle = false; 49 | for (int j = 0; j < v.size(); j++) 50 | { 51 | Edge ed = v[j]; 52 | int a = ed.u; 53 | int b = ed.v; 54 | int w = ed.w; 55 | if (dis[a] + w < dis[b]) 56 | { 57 | cycle = true; 58 | break; 59 | dis[b] = dis[a] + w; 60 | } 61 | } 62 | if (cycle) 63 | { 64 | cout << "Cycle Exist" << endl; 65 | } 66 | else 67 | { 68 | for (int i = 1; i <= n; i++) 69 | { 70 | cout << "Node " << i << ": " << dis[i] << endl; 71 | } 72 | } 73 | return 0; 74 | } -------------------------------------------------------------------------------- /Module 17/floyd_warshell.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | const int INF = 1e7; 4 | int main() 5 | { 6 | int n, e; 7 | cin >> n >> e; 8 | int dis[n + 1][n + 1]; 9 | for (int i = 1; i <= n; i++) 10 | { 11 | for (int j = 1; j <= n; j++) 12 | { 13 | dis[i][j] = INF; 14 | if (i == j) 15 | dis[i][j] = 0; 16 | } 17 | } 18 | while (e--) 19 | { 20 | int a, b, w; 21 | cin >> a >> b >> w; 22 | dis[a][b] = w; 23 | } 24 | for (int i = 1; i <= n; i++) 25 | { 26 | for (int j = 1; j <= n; j++) 27 | { 28 | if (dis[i][j] == INF) 29 | cout << "INF" 30 | << " "; 31 | else 32 | cout << dis[i][j] << " "; 33 | } 34 | cout << endl; 35 | } 36 | for (int k = 1; k <= n; k++) 37 | { 38 | for (int i = 1; i <= n; i++) 39 | { 40 | for (int j = 1; j <= n; j++) 41 | { 42 | if (dis[i][k] + dis[k][j] < dis[i][j]) 43 | { 44 | dis[i][j] = dis[i][k] + dis[k][j]; 45 | } 46 | } 47 | } 48 | } 49 | cout << "Updated" << endl; 50 | for (int i = 1; i <= n; i++) 51 | { 52 | for (int j = 1; j <= n; j++) 53 | { 54 | if (dis[i][j] == INF) 55 | cout << "INF" 56 | << " "; 57 | else 58 | cout << dis[i][j] << " "; 59 | } 60 | cout << endl; 61 | } 62 | return 0; 63 | } -------------------------------------------------------------------------------- /Module 18/.gitignore: -------------------------------------------------------------------------------- 1 | .cph/ 2 | .vscode/ 3 | *.txt 4 | *.exe 5 | *.bin -------------------------------------------------------------------------------- /Module 18/Building_Roads.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | const int N = 1e5 + 5; 4 | int parent[N]; 5 | int parentLevel[N]; 6 | void dsu_set(int n) 7 | { 8 | for (int i = 1; i <= n; i++) 9 | { 10 | parent[i] = -1; 11 | parentLevel[i] = 0; 12 | } 13 | } 14 | int dsu_find(int node) 15 | { 16 | while (parent[node] != -1) 17 | { 18 | node = parent[node]; 19 | } 20 | return node; 21 | } 22 | void dsu_union(int a, int b) 23 | { 24 | int leaderA = dsu_find(a); 25 | int leaderB = dsu_find(b); 26 | if (leaderA != leaderB) 27 | { 28 | if (parentLevel[leaderA] > parentLevel[leaderB]) 29 | { 30 | parent[leaderB] = leaderA; 31 | } 32 | else if (parentLevel[leaderB] > parentLevel[leaderA]) 33 | { 34 | parent[leaderA] = leaderB; 35 | } 36 | else 37 | { 38 | parent[leaderB] = leaderA; 39 | parentLevel[leaderA]++; 40 | } 41 | } 42 | } 43 | int main() 44 | { 45 | int n, e; 46 | cin >> n >> e; 47 | dsu_set(n); 48 | while (e--) 49 | { 50 | int a, b; 51 | cin >> a >> b; 52 | dsu_union(a, b); 53 | } 54 | map mp; 55 | for (int i = 1; i <= n; i++) 56 | { 57 | int ldr = dsu_find(i); 58 | mp[ldr] = true; 59 | } 60 | vector v; 61 | for (pair p : mp) 62 | { 63 | v.push_back(p.first); 64 | } 65 | cout << v.size() - 1 << endl; 66 | for (int i = 0; i < v.size() - 1; i++) 67 | { 68 | cout << v[i] << " " << v[i + 1] << endl; 69 | } 70 | return 0; 71 | } -------------------------------------------------------------------------------- /Module 18/Road_Construction.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | const int N = 1e5 + 5; 4 | int parent[N]; 5 | int parentSize[N]; 6 | void dsu_set(int n) 7 | { 8 | for (int i = 1; i <= n; i++) 9 | { 10 | parent[i] = -1; 11 | parentSize[i] = 1; 12 | } 13 | } 14 | int dsu_find(int node) 15 | { 16 | while (parent[node] != -1) 17 | { 18 | node = parent[node]; 19 | } 20 | return node; 21 | } 22 | int mx = 0; 23 | void dsu_union(int a, int b) 24 | { 25 | int leaderA = dsu_find(a); 26 | int leaderB = dsu_find(b); 27 | if (leaderA != leaderB) 28 | { 29 | if (parentSize[leaderA] > parentSize[leaderB]) 30 | { 31 | // A leader 32 | parent[leaderB] = leaderA; 33 | parentSize[leaderA] += parentSize[leaderB]; 34 | mx = max(mx, parentSize[leaderA]); 35 | } 36 | else 37 | { 38 | parent[leaderA] = leaderB; 39 | parentSize[leaderB] += parentSize[leaderA]; 40 | mx = max(mx, parentSize[leaderB]); 41 | } 42 | } 43 | } 44 | int main() 45 | { 46 | int n, e; 47 | cin >> n >> e; 48 | dsu_set(n); 49 | int cmp = n; 50 | while (e--) 51 | { 52 | int a, b; 53 | cin >> a >> b; 54 | int leaderA = dsu_find(a); 55 | int leaderB = dsu_find(b); 56 | if (leaderA != leaderB) 57 | { 58 | cmp--; 59 | dsu_union(a, b); 60 | } 61 | cout << cmp << " " << mx << endl; 62 | } 63 | return 0; 64 | } -------------------------------------------------------------------------------- /Module 18/find.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | int parent[8] = {-1, -1, 1, 1, 6, 4, -1, -1}; 4 | int find(int n) 5 | { 6 | while (parent[n] != -1) 7 | { 8 | n = parent[n]; 9 | } 10 | return n; 11 | } 12 | int main() 13 | { 14 | cout << find(7); 15 | return 0; 16 | } -------------------------------------------------------------------------------- /Module 18/undirected_cycle_detect.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | int parent[1000]; 4 | int parentLevel[1000]; 5 | void dsu_set(int n) 6 | { 7 | for (int i = 1; i <= n; i++) 8 | { 9 | parent[i] = -1; 10 | parentLevel[i] = 0; 11 | } 12 | } 13 | int dsu_find(int node) 14 | { 15 | while (parent[node] != -1) 16 | { 17 | node = parent[node]; 18 | } 19 | return node; 20 | } 21 | void dsu_union(int a, int b) 22 | { 23 | int leaderA = dsu_find(a); 24 | int leaderB = dsu_find(b); 25 | if (leaderA != leaderB) 26 | { 27 | if (parentLevel[leaderA] > parentLevel[leaderB]) 28 | { 29 | parent[leaderB] = leaderA; 30 | } 31 | else if (parentLevel[leaderB] > parentLevel[leaderA]) 32 | { 33 | parent[leaderA] = leaderB; 34 | } 35 | else 36 | { 37 | parent[leaderB] = leaderA; 38 | parentLevel[leaderA]++; 39 | } 40 | } 41 | } 42 | int main() 43 | { 44 | int n, e; 45 | cin >> n >> e; 46 | dsu_set(n); 47 | while (e--) 48 | { 49 | int a, b; 50 | cin >> a >> b; 51 | int leaderA = dsu_find(a); 52 | int leaderB = dsu_find(b); 53 | // cout << leaderA << " " << leaderB << endl; 54 | if (leaderA == leaderB) 55 | { 56 | cout << "Cycel detected in between: " << a << " " << b << endl; 57 | } 58 | else 59 | { 60 | dsu_union(a, b); 61 | } 62 | } 63 | return 0; 64 | } -------------------------------------------------------------------------------- /Module 18/union.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | int parent[1000]; 4 | int parentSize[1000]; 5 | void dsu_set(int n) 6 | { 7 | for (int i = 1; i <= n; i++) 8 | { 9 | parent[i] = -1; 10 | parentSize[i] = 1; 11 | } 12 | } 13 | int dsu_find(int node) 14 | { 15 | while (parent[node] != -1) 16 | { 17 | node = parent[node]; 18 | } 19 | return node; 20 | } 21 | void dsu_union(int a, int b) 22 | { 23 | int leaderA = dsu_find(a); 24 | int leaderB = dsu_find(b); 25 | if (leaderA != leaderB) 26 | { 27 | parent[leaderB] = leaderA; 28 | } 29 | } 30 | int main() 31 | { 32 | int n, e; 33 | cin >> n >> e; 34 | dsu_set(n); 35 | while (e--) 36 | { 37 | int a, b; 38 | cin >> a >> b; 39 | dsu_union(a, b); 40 | } 41 | cout << dsu_find(5); 42 | return 0; 43 | } -------------------------------------------------------------------------------- /Module 18/union_by_rank.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | int parent[1000]; 4 | int parentLevel[1000]; 5 | void dsu_set(int n) 6 | { 7 | for (int i = 1; i <= n; i++) 8 | { 9 | parent[i] = -1; 10 | parentLevel[i] = 0; 11 | } 12 | } 13 | int dsu_find(int node) 14 | { 15 | while (parent[node] != -1) 16 | { 17 | node = parent[node]; 18 | } 19 | return node; 20 | } 21 | void dsu_union(int a, int b) 22 | { 23 | int leaderA = dsu_find(a); 24 | int leaderB = dsu_find(b); 25 | if (leaderA != leaderB) 26 | { 27 | if (parentLevel[leaderA] > parentLevel[leaderB]) 28 | { 29 | parent[leaderB] = leaderA; 30 | } 31 | else if (parentLevel[leaderB] > parentLevel[leaderA]) 32 | { 33 | parent[leaderA] = leaderB; 34 | } 35 | else 36 | { 37 | parent[leaderB] = leaderA; 38 | parentLevel[leaderA]++; 39 | } 40 | } 41 | } 42 | int main() 43 | { 44 | int n, e; 45 | cin >> n >> e; 46 | dsu_set(n); 47 | while (e--) 48 | { 49 | int a, b; 50 | cin >> a >> b; 51 | dsu_union(a, b); 52 | } 53 | cout << dsu_find(2); 54 | return 0; 55 | } -------------------------------------------------------------------------------- /Module 18/union_by_size.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | int parent[1000]; 4 | int parentSize[1000]; 5 | void dsu_set(int n) 6 | { 7 | for (int i = 1; i <= n; i++) 8 | { 9 | parent[i] = -1; 10 | parentSize[i] = 1; 11 | } 12 | } 13 | int dsu_find(int node) 14 | { 15 | while (parent[node] != -1) 16 | { 17 | node = parent[node]; 18 | } 19 | return node; 20 | } 21 | void dsu_union(int a, int b) 22 | { 23 | int leaderA = dsu_find(a); 24 | int leaderB = dsu_find(b); 25 | if (leaderA != leaderB) 26 | { 27 | if (parentSize[leaderA] > parentSize[leaderB]) 28 | { 29 | // A leader 30 | parent[leaderB] = leaderA; 31 | parentSize[leaderA] += parentSize[leaderB]; 32 | } 33 | else 34 | { 35 | parent[leaderA] = leaderB; 36 | parentSize[leaderB] += parentSize[leaderA]; 37 | } 38 | } 39 | } 40 | int main() 41 | { 42 | int n, e; 43 | cin >> n >> e; 44 | dsu_set(n); 45 | while (e--) 46 | { 47 | int a, b; 48 | cin >> a >> b; 49 | dsu_union(a, b); 50 | } 51 | cout << dsu_find(6); 52 | return 0; 53 | } -------------------------------------------------------------------------------- /Module 19/.gitignore: -------------------------------------------------------------------------------- 1 | .cph/ 2 | .vscode/ 3 | *.txt 4 | *.exe 5 | *.bin -------------------------------------------------------------------------------- /Module 19/Road_Reparation.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #define pi pair 3 | using namespace std; 4 | const int N = 1e5 + 5; 5 | vector v[N]; 6 | bool vis[N]; 7 | class Edge 8 | { 9 | public: 10 | int a, b, w; 11 | Edge(int a, int b, int w) 12 | { 13 | this->a = a; 14 | this->b = b; 15 | this->w = w; 16 | } 17 | }; 18 | class cmp 19 | { 20 | public: 21 | bool operator()(Edge a, Edge b) 22 | { 23 | return a.w > b.w; 24 | } 25 | }; 26 | void prims(int s, int n) 27 | { 28 | priority_queue, cmp> pq; 29 | vector edgeList; 30 | pq.push(Edge(s, s, 0)); 31 | int cnt = 0; 32 | while (!pq.empty()) 33 | { 34 | Edge parent = pq.top(); 35 | pq.pop(); 36 | int a = parent.a; 37 | int b = parent.b; 38 | int w = parent.w; 39 | if (vis[b]) 40 | continue; 41 | vis[b] = true; 42 | cnt++; 43 | edgeList.push_back(parent); 44 | for (int i = 0; i < v[b].size(); i++) 45 | { 46 | pi child = v[b][i]; 47 | if (!vis[child.first]) 48 | { 49 | pq.push(Edge(b, child.first, child.second)); 50 | } 51 | } 52 | } 53 | edgeList.erase(edgeList.begin()); 54 | long long sum = 0; 55 | for (Edge val : edgeList) 56 | { 57 | sum += (long long)(val.w); 58 | } 59 | if (cnt == n) 60 | { 61 | cout << sum << endl; 62 | } 63 | else 64 | { 65 | cout << "IMPOSSIBLE" << endl; 66 | } 67 | } 68 | int main() 69 | { 70 | int n, e; 71 | cin >> n >> e; 72 | while (e--) 73 | { 74 | int a, b, w; 75 | cin >> a >> b >> w; 76 | v[a].push_back({b, w}); 77 | v[b].push_back({a, w}); 78 | } 79 | prims(1, n); 80 | return 0; 81 | } -------------------------------------------------------------------------------- /Module 19/Road_Reparation_Kruskal.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | class Edge 4 | { 5 | public: 6 | int a, b, w; 7 | Edge(int a, int b, int w) 8 | { 9 | this->a = a; 10 | this->b = b; 11 | this->w = w; 12 | } 13 | }; 14 | bool cmp(Edge a, Edge b) 15 | { 16 | return a.w < b.w; 17 | } 18 | const int N = 1e5 + 5; 19 | int parent[N]; 20 | int parentSize[N]; 21 | void dsu_set(int n) 22 | { 23 | for (int i = 1; i <= n; i++) 24 | { 25 | parent[i] = -1; 26 | parentSize[i] = 1; 27 | } 28 | } 29 | int dsu_find(int node) 30 | { 31 | while (parent[node] != -1) 32 | { 33 | node = parent[node]; 34 | } 35 | return node; 36 | } 37 | void dsu_union(int a, int b) 38 | { 39 | int leaderA = dsu_find(a); 40 | int leaderB = dsu_find(b); 41 | if (leaderA != leaderB) 42 | { 43 | if (parentSize[leaderA] > parentSize[leaderB]) 44 | { 45 | // A leader 46 | parent[leaderB] = leaderA; 47 | parentSize[leaderA] += parentSize[leaderB]; 48 | } 49 | else 50 | { 51 | parent[leaderA] = leaderB; 52 | parentSize[leaderB] += parentSize[leaderA]; 53 | } 54 | } 55 | } 56 | int main() 57 | { 58 | int n, e; 59 | cin >> n >> e; 60 | vector v; 61 | vector ans; 62 | dsu_set(n); 63 | while (e--) 64 | { 65 | int a, b, w; 66 | cin >> a >> b >> w; 67 | v.push_back(Edge(a, b, w)); 68 | } 69 | sort(v.begin(), v.end(), cmp); 70 | for (Edge val : v) 71 | { 72 | int a = val.a; 73 | int b = val.b; 74 | int w = val.w; 75 | int leaderA = dsu_find(a); 76 | int leaderB = dsu_find(b); 77 | if (leaderA == leaderB) 78 | continue; 79 | ans.push_back(val); 80 | dsu_union(a, b); 81 | } 82 | long long sum = 0; 83 | for (Edge val : ans) 84 | { 85 | sum += (long long)val.w; 86 | } 87 | if (ans.size() == n - 1) 88 | { 89 | cout << sum << endl; 90 | } 91 | else 92 | { 93 | cout << "IMPOSSIBLE" << endl; 94 | } 95 | return 0; 96 | } -------------------------------------------------------------------------------- /Module 19/kruskal_mst.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | class Edge 4 | { 5 | public: 6 | int a, b, w; 7 | Edge(int a, int b, int w) 8 | { 9 | this->a = a; 10 | this->b = b; 11 | this->w = w; 12 | } 13 | }; 14 | bool cmp(Edge a, Edge b) 15 | { 16 | return a.w < b.w; 17 | } 18 | const int N = 1e5 + 5; 19 | int parent[N]; 20 | int parentSize[N]; 21 | void dsu_set(int n) 22 | { 23 | for (int i = 1; i <= n; i++) 24 | { 25 | parent[i] = -1; 26 | parentSize[i] = 1; 27 | } 28 | } 29 | int dsu_find(int node) 30 | { 31 | while (parent[node] != -1) 32 | { 33 | node = parent[node]; 34 | } 35 | return node; 36 | } 37 | void dsu_union(int a, int b) 38 | { 39 | int leaderA = dsu_find(a); 40 | int leaderB = dsu_find(b); 41 | if (leaderA != leaderB) 42 | { 43 | if (parentSize[leaderA] > parentSize[leaderB]) 44 | { 45 | // A leader 46 | parent[leaderB] = leaderA; 47 | parentSize[leaderA] += parentSize[leaderB]; 48 | } 49 | else 50 | { 51 | parent[leaderA] = leaderB; 52 | parentSize[leaderB] += parentSize[leaderA]; 53 | } 54 | } 55 | } 56 | int main() 57 | { 58 | int n, e; 59 | cin >> n >> e; 60 | vector v; 61 | vector ans; 62 | dsu_set(n); 63 | while (e--) 64 | { 65 | int a, b, w; 66 | cin >> a >> b >> w; 67 | v.push_back(Edge(a, b, w)); 68 | } 69 | sort(v.begin(), v.end(), cmp); 70 | for (Edge val : v) 71 | { 72 | int a = val.a; 73 | int b = val.b; 74 | int w = val.w; 75 | int leaderA = dsu_find(a); 76 | int leaderB = dsu_find(b); 77 | if (leaderA == leaderB) 78 | continue; 79 | ans.push_back(val); 80 | dsu_union(a, b); 81 | } 82 | for (Edge val : ans) 83 | { 84 | cout << val.a << " " << val.b << " " << val.w << endl; 85 | } 86 | return 0; 87 | } -------------------------------------------------------------------------------- /Module 19/prims_mst.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #define pi pair 3 | using namespace std; 4 | const int N = 1e5 + 5; 5 | vector v[N]; 6 | bool vis[N]; 7 | class Edge 8 | { 9 | public: 10 | int a, b, w; 11 | Edge(int a, int b, int w) 12 | { 13 | this->a = a; 14 | this->b = b; 15 | this->w = w; 16 | } 17 | }; 18 | class cmp 19 | { 20 | public: 21 | bool operator()(Edge a, Edge b) 22 | { 23 | return a.w > b.w; 24 | } 25 | }; 26 | void prims(int s) 27 | { 28 | priority_queue, cmp> pq; 29 | vector edgeList; 30 | pq.push(Edge(s, s, 0)); 31 | while (!pq.empty()) 32 | { 33 | Edge parent = pq.top(); 34 | pq.pop(); 35 | int a = parent.a; 36 | int b = parent.b; 37 | int w = parent.w; 38 | if (vis[b]) 39 | continue; 40 | vis[b] = true; 41 | edgeList.push_back(parent); 42 | for (int i = 0; i < v[b].size(); i++) 43 | { 44 | pi child = v[b][i]; 45 | if (!vis[child.first]) 46 | { 47 | pq.push(Edge(b, child.first, child.second)); 48 | } 49 | } 50 | } 51 | edgeList.erase(edgeList.begin()); 52 | for (Edge val : edgeList) 53 | { 54 | cout << val.a << " " << val.b << " " << val.w << endl; 55 | } 56 | } 57 | int main() 58 | { 59 | int n, e; 60 | cin >> n >> e; 61 | while (e--) 62 | { 63 | int a, b, w; 64 | cin >> a >> b >> w; 65 | v[a].push_back({b, w}); 66 | v[b].push_back({a, w}); 67 | } 68 | prims(1); 69 | return 0; 70 | } -------------------------------------------------------------------------------- /Module 21/.gitignore: -------------------------------------------------------------------------------- 1 | .cph/ 2 | .vscode/ 3 | *.txt 4 | *.exe 5 | *.bin -------------------------------------------------------------------------------- /Module 21/A_Frog_1.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | int main() 4 | { 5 | int n; 6 | cin >> n; 7 | int cost[n + 1], dp[n + 1]; 8 | for (int i = 1; i <= n; i++) 9 | { 10 | cin >> cost[i]; 11 | } 12 | dp[1] = 0; 13 | dp[2] = abs(cost[2] - cost[1]); 14 | for (int i = 3; i <= n; i++) 15 | { 16 | // int choice1 = dp[i - 2] + abs(cost[i] - cost[i - 2]); 17 | // int choice2 = dp[i - 1] + abs(cost[i] - cost[i - 1]); 18 | dp[i] = min(dp[i - 2] + abs(cost[i] - cost[i - 2]), dp[i - 1] + abs(cost[i] - cost[i - 1])); // dp state 19 | } 20 | cout << dp[n] << endl; 21 | return 0; 22 | } 23 | -------------------------------------------------------------------------------- /Module 21/A_Frog_1_Top_Down.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | const int N = 1e5 + 5; 4 | int dp[N]; 5 | int solve(int a[], int n) 6 | { 7 | if (n == 1) 8 | { 9 | return 0; 10 | } 11 | if (dp[n] != -1) 12 | return dp[n]; 13 | else if (n == 2) 14 | { 15 | return dp[n] = abs(a[2] - a[1]); 16 | } 17 | else 18 | { 19 | int choice1 = solve(a, n - 1) + abs(a[n] - a[n - 1]); 20 | int choice2 = solve(a, n - 2) + abs(a[n] - a[n - 2]); 21 | return dp[n] = min(choice1, choice2); 22 | } 23 | } 24 | int main() 25 | { 26 | int n; 27 | cin >> n; 28 | int a[n + 1]; 29 | for (int i = 1; i <= n; i++) 30 | { 31 | dp[i] = -1; 32 | cin >> a[i]; 33 | } 34 | cout << solve(a, n); 35 | return 0; 36 | } -------------------------------------------------------------------------------- /Module 21/fibonacci_loop.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #define ll long long 3 | using namespace std; 4 | int main() 5 | { 6 | ll n; 7 | cin >> n; 8 | ll a[n + 1]; 9 | a[0] = 1; 10 | a[1] = 1; 11 | for (int i = 2; i <= n; i++) 12 | { 13 | a[i] = a[i - 1] + a[i - 2]; 14 | } 15 | cout << a[n] << endl; 16 | return 0; 17 | } -------------------------------------------------------------------------------- /Module 21/fibonacci_memoization.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #define ll long long 3 | using namespace std; 4 | const ll N = 1e5 + 5; 5 | ll save[N]; 6 | ll fibo(ll n) 7 | { 8 | if (n == 0 || n == 1) 9 | return 1; 10 | // memoization 11 | if (save[n] != -1) 12 | { 13 | return save[n]; 14 | } 15 | ll ans1 = fibo(n - 1); 16 | ll ans2 = fibo(n - 2); 17 | save[n] = ans1 + ans2; 18 | return save[n]; 19 | } 20 | int main() 21 | { 22 | ll n; 23 | cin >> n; 24 | for (int i = 0; i <= n; i++) 25 | { 26 | save[i] = -1; 27 | } 28 | cout << fibo(n) << endl; 29 | return 0; 30 | } -------------------------------------------------------------------------------- /Module 21/fibonacci_recursion.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | int fibo(int n) 4 | { 5 | if (n == 0 || n == 1) 6 | return 1; 7 | int ans1 = fibo(n - 1); 8 | int ans2 = fibo(n - 2); 9 | return ans1 + ans2; 10 | } 11 | int main() 12 | { 13 | int n; 14 | cin >> n; 15 | cout << fibo(n) << endl; 16 | return 0; 17 | } -------------------------------------------------------------------------------- /Module 22/.gitignore: -------------------------------------------------------------------------------- 1 | .cph/ 2 | .vscode/ 3 | *.txt 4 | *.exe 5 | *.bin -------------------------------------------------------------------------------- /Module 22/0-1_knapsack_bottom_up.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | int main() 4 | { 5 | int n; 6 | cin >> n; 7 | int v[n], w[n]; 8 | for (int i = 0; i < n; i++) 9 | { 10 | cin >> v[i]; 11 | } 12 | for (int i = 0; i < n; i++) 13 | { 14 | cin >> w[i]; 15 | } 16 | int s; 17 | cin >> s; 18 | int dp[n + 1][s + 1]; 19 | for (int i = 0; i <= n; i++) 20 | { 21 | for (int j = 0; j <= s; j++) 22 | { 23 | if (i == 0 || j == 0) 24 | dp[i][j] = 0; 25 | } 26 | } 27 | for (int i = 1; i <= n; i++) 28 | { 29 | for (int j = 1; j <= s; j++) 30 | { 31 | if (w[i - 1] <= j) 32 | { 33 | // dp state 34 | dp[i][j] = max(v[i - 1] + dp[i - 1][j - w[i - 1]], dp[i - 1][j]); 35 | } 36 | else 37 | { 38 | dp[i][j] = dp[i - 1][j]; 39 | } 40 | } 41 | } 42 | for (int i = 0; i <= n; i++) 43 | { 44 | for (int j = 0; j <= s; j++) 45 | { 46 | cout << dp[i][j] << " "; 47 | } 48 | cout << endl; 49 | } 50 | return 0; 51 | } -------------------------------------------------------------------------------- /Module 22/0-1_knapsack_memoization.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | int dp[1005][1005]; 4 | int knapsack(int n, int s, int v[], int w[]) 5 | { 6 | // base case 7 | if (n == 0 || s == 0) 8 | return 0; 9 | if (dp[n][s] != -1) 10 | { 11 | return dp[n][s]; 12 | } 13 | if (w[n - 1] <= s) 14 | { 15 | int op1 = knapsack(n - 1, s - w[n - 1], v, w) + v[n - 1]; 16 | int op2 = knapsack(n - 1, s, v, w); 17 | return dp[n][s] = max(op1, op2); 18 | } 19 | else 20 | { 21 | return dp[n][s] = knapsack(n - 1, s, v, w); 22 | } 23 | } 24 | int main() 25 | { 26 | int n; 27 | cin >> n; 28 | int v[n], w[n]; 29 | for (int i = 0; i < n; i++) 30 | { 31 | cin >> v[i]; 32 | } 33 | for (int i = 0; i < n; i++) 34 | { 35 | cin >> w[i]; 36 | } 37 | int s; 38 | cin >> s; 39 | for (int i = 0; i <= n; i++) 40 | { 41 | for (int j = 0; j <= s; j++) 42 | { 43 | dp[i][j] = -1; 44 | } 45 | } 46 | cout << knapsack(n, s, v, w); 47 | return 0; 48 | } -------------------------------------------------------------------------------- /Module 22/0-1_knapsack_recursion.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | int knapsack(int n, int s, int v[], int w[]) 4 | { 5 | // base case 6 | if (n == 0 || s == 0) 7 | return 0; 8 | if (w[n - 1] <= s) 9 | { 10 | int op1 = knapsack(n - 1, s - w[n - 1], v, w) + v[n - 1]; 11 | int op2 = knapsack(n - 1, s, v, w); 12 | return max(op1, op2); 13 | } 14 | else 15 | { 16 | return knapsack(n - 1, s, v, w); 17 | } 18 | } 19 | int main() 20 | { 21 | int n; 22 | cin >> n; 23 | int v[n], w[n]; 24 | for (int i = 0; i < n; i++) 25 | { 26 | cin >> v[i]; 27 | } 28 | for (int i = 0; i < n; i++) 29 | { 30 | cin >> w[i]; 31 | } 32 | int s; 33 | cin >> s; 34 | cout << knapsack(n, s, v, w); 35 | return 0; 36 | } -------------------------------------------------------------------------------- /Module 22/U_Knapsack.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | int knapsack(int n, int s, int v[], int w[]) 4 | { 5 | // base case 6 | if (n == 0 || s == 0) 7 | return 0; 8 | if (w[n - 1] <= s) 9 | { 10 | int op1 = knapsack(n - 1, s - w[n - 1], v, w) + v[n - 1]; 11 | int op2 = knapsack(n - 1, s, v, w); 12 | return max(op1, op2); 13 | } 14 | else 15 | { 16 | return knapsack(n - 1, s, v, w); 17 | } 18 | } 19 | int main() 20 | { 21 | int n, s; 22 | cin >> n >> s; 23 | int v[n], w[n]; 24 | for (int i = 0; i < n; i++) 25 | { 26 | cin >> w[i] >> v[i]; 27 | } 28 | cout << knapsack(n, s, v, w); 29 | return 0; 30 | } -------------------------------------------------------------------------------- /Module 22/knapsack-geeksforgeeks.cpp: -------------------------------------------------------------------------------- 1 | class Solution 2 | { 3 | public: 4 | // Function to return max value that can be put in knapsack of capacity W. 5 | 6 | int knapSack(int s, int w[], int v[], int n) 7 | { 8 | // Your code here 9 | int dp[n + 1][s + 1]; 10 | for (int i = 0; i <= n; i++) 11 | { 12 | for (int j = 0; j <= s; j++) 13 | { 14 | if (i == 0 || j == 0) 15 | dp[i][j] = 0; 16 | } 17 | } 18 | for (int i = 1; i <= n; i++) 19 | { 20 | for (int j = 1; j <= s; j++) 21 | { 22 | if (w[i - 1] <= j) 23 | { 24 | dp[i][j] = max(dp[i - 1][j - w[i - 1]] + v[i - 1], dp[i - 1][j]); 25 | } 26 | else 27 | { 28 | dp[i][j] = dp[i - 1][j]; 29 | } 30 | } 31 | } 32 | return dp[n][s]; 33 | } 34 | }; -------------------------------------------------------------------------------- /Module 23/.gitignore: -------------------------------------------------------------------------------- 1 | .cph/ 2 | .vscode/ 3 | *.txt 4 | *.exe 5 | *.bin -------------------------------------------------------------------------------- /Module 23/count_of_subset_sum.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | int dp[1005][1005]; 4 | int subset_sum(int n, int a[], int s) 5 | { 6 | if (n == 0) 7 | { 8 | if (s == 0) 9 | return 1; 10 | else 11 | return 0; 12 | } 13 | if (dp[n][s] != -1) 14 | return dp[n][s]; 15 | if (a[n - 1] <= s) 16 | { 17 | int op1 = subset_sum(n - 1, a, s - a[n - 1]); 18 | int op2 = subset_sum(n - 1, a, s); 19 | return dp[n][s] = op1 + op2; 20 | } 21 | else 22 | { 23 | return dp[n][s] = subset_sum(n - 1, a, s); 24 | } 25 | } 26 | int main() 27 | { 28 | int n; 29 | cin >> n; 30 | int a[n]; 31 | for (int i = 0; i < n; i++) 32 | { 33 | cin >> a[i]; 34 | } 35 | int s; 36 | cin >> s; 37 | dp[0][0] = true; 38 | for (int i = 1; i <= s; i++) 39 | { 40 | dp[0][i] = 0; 41 | } 42 | for (int i = 1; i <= n; i++) 43 | { 44 | for (int j = 0; j <= s; j++) 45 | { 46 | if (a[i - 1] <= j) 47 | { 48 | dp[i][j] = dp[i - 1][j - a[i - 1]] + dp[i - 1][j]; 49 | } 50 | else 51 | { 52 | dp[i][j] = dp[i - 1][j]; 53 | } 54 | } 55 | } 56 | for (int i = 0; i <= n; i++) 57 | { 58 | for (int j = 0; j <= s; j++) 59 | { 60 | cout << dp[i][j] << " "; 61 | } 62 | cout << endl; 63 | } 64 | return 0; 65 | } -------------------------------------------------------------------------------- /Module 23/equal_sum.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | int main() 4 | { 5 | int n; 6 | cin >> n; 7 | int s = 0; 8 | int a[n]; 9 | for (int i = 0; i < n; i++) 10 | { 11 | cin >> a[i]; 12 | s += a[i]; 13 | } 14 | if (s % 2 == 0) 15 | { 16 | int sum = s / 2; 17 | bool dp[n + 1][sum + 1]; 18 | dp[0][0] = true; 19 | for (int i = 1; i <= sum; i++) 20 | dp[0][i] = false; 21 | for (int i = 1; i <= n; i++) 22 | { 23 | for (int j = 0; j <= sum; j++) 24 | { 25 | if (a[i - 1] <= j) 26 | { 27 | dp[i][j] = dp[i - 1][j - a[i - 1]] || dp[i - 1][j]; 28 | } 29 | else 30 | { 31 | dp[i][j] = dp[i - 1][j]; 32 | } 33 | } 34 | } 35 | if (dp[n][sum]) 36 | cout << "YES" << endl; 37 | else 38 | cout << "NO" << endl; 39 | } 40 | else 41 | { 42 | cout << "NO" << endl; 43 | } 44 | return 0; 45 | } -------------------------------------------------------------------------------- /Module 23/minimum_subset_sum_difference.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | int main() 4 | { 5 | int n; 6 | cin >> n; 7 | int a[n], s = 0; 8 | for (int i = 0; i < n; i++) 9 | { 10 | cin >> a[i]; 11 | s += a[i]; 12 | } 13 | bool dp[n + 1][s + 1]; 14 | dp[0][0] = true; 15 | for (int i = 1; i <= s; i++) 16 | dp[0][i] = false; 17 | for (int i = 1; i <= n; i++) 18 | { 19 | for (int j = 0; j <= s; j++) 20 | { 21 | if (a[i - 1] <= j) 22 | { 23 | dp[i][j] = dp[i - 1][j - a[i - 1]] || dp[i - 1][j]; 24 | } 25 | else 26 | { 27 | dp[i][j] = dp[i - 1][j]; 28 | } 29 | } 30 | } 31 | vector v; 32 | for (int i = 0; i <= n; i++) 33 | { 34 | for (int j = 0; j <= s; j++) 35 | { 36 | if (dp[i][j] == 1) 37 | v.push_back(j); 38 | } 39 | } 40 | int ans = INT_MAX; 41 | for (int val : v) 42 | { 43 | int s1 = val; 44 | int s2 = s - s1; 45 | ans = min(ans, abs(s1 - s2)); 46 | } 47 | cout << ans << endl; 48 | return 0; 49 | } -------------------------------------------------------------------------------- /Module 23/subset_sum_bottom_up.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | int main() 4 | { 5 | int n; 6 | cin >> n; 7 | int a[n]; 8 | for (int i = 0; i < n; i++) 9 | { 10 | cin >> a[i]; 11 | } 12 | int s; 13 | cin >> s; 14 | bool dp[n + 1][s + 1]; 15 | dp[0][0] = true; 16 | for (int i = 1; i <= s; i++) 17 | { 18 | dp[0][i] = false; 19 | } 20 | for (int i = 1; i <= n; i++) 21 | { 22 | for (int j = 0; j <= s; j++) 23 | { 24 | if (a[i - 1] <= j) 25 | { 26 | dp[i][j] = dp[i - 1][j - a[i - 1]] || dp[i - 1][j]; 27 | } 28 | else 29 | { 30 | dp[i][j] = dp[i - 1][j]; 31 | } 32 | } 33 | } 34 | for (int i = 0; i <= n; i++) 35 | { 36 | for (int j = 0; j <= s; j++) 37 | { 38 | if (dp[i][j]) 39 | cout << "T "; 40 | else 41 | cout << "F "; 42 | } 43 | cout << endl; 44 | } 45 | // if (dp[n][s]) 46 | // cout << "YES" << endl; 47 | // else 48 | // cout << "NO" << endl; 49 | return 0; 50 | } -------------------------------------------------------------------------------- /Module 23/subset_sum_top_down.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | int dp[1005][1005]; 4 | bool subset_sum(int n, int a[], int s) 5 | { 6 | if (n == 0) 7 | { 8 | if (s == 0) 9 | return true; 10 | else 11 | return false; 12 | } 13 | if (dp[n][s] != -1) 14 | return dp[n][s]; 15 | if (a[n - 1] <= s) 16 | { 17 | bool op1 = subset_sum(n - 1, a, s - a[n - 1]); 18 | bool op2 = subset_sum(n - 1, a, s); 19 | return dp[n][s] = op1 || op2; 20 | } 21 | else 22 | { 23 | return dp[n][s] = subset_sum(n - 1, a, s); 24 | } 25 | } 26 | int main() 27 | { 28 | int n; 29 | cin >> n; 30 | int a[n]; 31 | for (int i = 0; i < n; i++) 32 | { 33 | cin >> a[i]; 34 | } 35 | int s; 36 | cin >> s; 37 | for (int i = 0; i <= n; i++) 38 | { 39 | for (int j = 0; j <= s; j++) 40 | { 41 | dp[i][j] = -1; 42 | } 43 | } 44 | if (subset_sum(n, a, s)) 45 | { 46 | cout << "YES" << endl; 47 | } 48 | else 49 | { 50 | cout << "NO" << endl; 51 | } 52 | return 0; 53 | } -------------------------------------------------------------------------------- /Module 25/.gitignore: -------------------------------------------------------------------------------- 1 | .cph/ 2 | .vscode/ 3 | *.txt 4 | *.exe 5 | *.bin -------------------------------------------------------------------------------- /Module 25/coin_change_1.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | int main() 4 | { 5 | int n; 6 | cin >> n; 7 | int w[n]; 8 | for (int i = 0; i < n; i++) 9 | { 10 | cin >> w[i]; 11 | } 12 | int s; 13 | cin >> s; 14 | int dp[n + 1][s + 1]; 15 | dp[0][0] = 1; 16 | for (int i = 1; i <= s; i++) 17 | dp[0][i] = 0; 18 | for (int i = 1; i <= n; i++) 19 | { 20 | for (int j = 0; j <= s; j++) 21 | { 22 | if (w[i - 1] <= j) 23 | { 24 | dp[i][j] = dp[i][j - w[i - 1]] + dp[i - 1][j]; 25 | } 26 | else 27 | { 28 | dp[i][j] = dp[i - 1][j]; 29 | } 30 | } 31 | } 32 | cout << dp[n][s] << endl; 33 | return 0; 34 | } -------------------------------------------------------------------------------- /Module 25/coin_change_2.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | int main() 4 | { 5 | int n; 6 | cin >> n; 7 | int w[n]; 8 | for (int i = 0; i < n; i++) 9 | { 10 | cin >> w[i]; 11 | } 12 | int s; 13 | cin >> s; 14 | int dp[n + 1][s + 1]; 15 | dp[0][0] = 0; 16 | for (int i = 1; i <= s; i++) 17 | dp[0][i] = INT_MAX - 1; 18 | for (int i = 1; i <= n; i++) 19 | { 20 | for (int j = 0; j <= s; j++) 21 | { 22 | if (w[i - 1] <= j) 23 | { 24 | dp[i][j] = min(1 + dp[i][j - w[i - 1]], dp[i - 1][j]); 25 | } 26 | else 27 | { 28 | dp[i][j] = dp[i - 1][j]; 29 | } 30 | } 31 | } 32 | // for (int i = 0; i <= n; i++) 33 | // { 34 | // for (int j = 0; j <= s; j++) 35 | // { 36 | // cout << dp[i][j] << " "; 37 | // } 38 | // cout << endl; 39 | // } 40 | if (dp[n][s] == INT_MAX - 1) 41 | cout << "Not Possible" << endl; 42 | else 43 | cout << dp[n][s] << endl; 44 | return 0; 45 | } -------------------------------------------------------------------------------- /Module 25/rod_cutting.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | int dp[1005][1005]; 4 | int unbounded_knapsack(int n, int s, int val[], int w[]) 5 | { 6 | if (n == 0 || s == 0) 7 | return 0; 8 | if (dp[n][s] != -1) 9 | return dp[n][s]; 10 | if (w[n - 1] <= s) 11 | { 12 | int ch1 = val[n - 1] + unbounded_knapsack(n, s - w[n - 1], val, w); 13 | int ch2 = unbounded_knapsack(n - 1, s, val, w); 14 | return dp[n][s] = max(ch1, ch2); 15 | } 16 | else 17 | { 18 | return dp[n][s] = unbounded_knapsack(n - 1, s, val, w); 19 | } 20 | } 21 | int main() 22 | { 23 | int n; 24 | cin >> n; 25 | int val[n], w[n]; 26 | for (int i = 0; i <= n; i++) 27 | { 28 | for (int j = 0; j <= n; j++) 29 | { 30 | dp[i][j] = -1; 31 | } 32 | } 33 | for (int i = 0; i < n; i++) 34 | { 35 | cin >> val[i]; 36 | w[i] = i + 1; 37 | } 38 | cout << unbounded_knapsack(n, n, val, w) << endl; 39 | return 0; 40 | } -------------------------------------------------------------------------------- /Module 25/unbounded_knapsack.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | int dp[1005][1005]; 4 | int unbounded_knapsack(int n, int s, int val[], int w[]) 5 | { 6 | if (n == 0 || s == 0) 7 | return 0; 8 | if (dp[n][s] != -1) 9 | return dp[n][s]; 10 | if (w[n - 1] <= s) 11 | { 12 | int ch1 = val[n - 1] + unbounded_knapsack(n, s - w[n - 1], val, w); 13 | int ch2 = unbounded_knapsack(n - 1, s, val, w); 14 | return dp[n][s] = max(ch1, ch2); 15 | } 16 | else 17 | { 18 | return dp[n][s] = unbounded_knapsack(n - 1, s, val, w); 19 | } 20 | } 21 | int main() 22 | { 23 | int n, s; 24 | cin >> n >> s; 25 | int val[n], w[n]; 26 | for (int i = 0; i <= n; i++) 27 | { 28 | for (int j = 0; j <= s; j++) 29 | { 30 | dp[i][j] = -1; 31 | } 32 | } 33 | for (int i = 0; i < n; i++) 34 | { 35 | cin >> val[i]; 36 | } 37 | for (int i = 0; i < n; i++) 38 | { 39 | cin >> w[i]; 40 | } 41 | cout << unbounded_knapsack(n, s, val, w); 42 | return 0; 43 | } -------------------------------------------------------------------------------- /Module 25/unbounded_knapsack_bottom_up.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | int main() 4 | { 5 | int n, s; 6 | cin >> n >> s; 7 | int val[n], w[n]; 8 | int dp[n + 1][s + 1]; 9 | for (int i = 0; i <= n; i++) 10 | { 11 | for (int j = 0; j <= s; j++) 12 | { 13 | if (i == 0 || j == 0) 14 | dp[i][j] = 0; 15 | } 16 | } 17 | for (int i = 0; i < n; i++) 18 | { 19 | cin >> val[i]; 20 | } 21 | for (int i = 0; i < n; i++) 22 | { 23 | cin >> w[i]; 24 | } 25 | for (int i = 1; i <= n; i++) 26 | { 27 | for (int j = 1; j <= s; j++) 28 | { 29 | if (w[i - 1] <= j) 30 | { 31 | dp[i][j] = max(val[i - 1] + dp[i][j - w[i - 1]], dp[i - 1][j]); 32 | } 33 | else 34 | { 35 | dp[i][j] = dp[i - 1][j]; 36 | } 37 | } 38 | } 39 | cout << dp[n][s] << endl; 40 | return 0; 41 | } -------------------------------------------------------------------------------- /Module 26/.gitignore: -------------------------------------------------------------------------------- 1 | .cph/ 2 | .vscode/ 3 | *.txt 4 | *.exe 5 | *.bin -------------------------------------------------------------------------------- /Module 26/lcs_bottom_up.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | int main() 4 | { 5 | string a, b; 6 | cin >> a >> b; 7 | int n = a.size(), m = b.size(); 8 | int dp[n + 1][m + 1]; 9 | for (int i = 0; i <= n; i++) 10 | { 11 | for (int j = 0; j <= m; j++) 12 | { 13 | if (i == 0 || j == 0) 14 | dp[i][j] = 0; 15 | } 16 | } 17 | for (int i = 1; i <= n; i++) 18 | { 19 | for (int j = 1; j <= m; j++) 20 | { 21 | if (a[i - 1] == b[j - 1]) 22 | { 23 | dp[i][j] = dp[i - 1][j - 1] + 1; 24 | } 25 | else 26 | { 27 | dp[i][j] = max(dp[i - 1][j], dp[i][j - 1]); 28 | } 29 | } 30 | } 31 | cout << dp[n][m] << endl; 32 | return 0; 33 | } -------------------------------------------------------------------------------- /Module 26/lcs_print.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | int main() 4 | { 5 | string a, b; 6 | cin >> a >> b; 7 | int n = a.size(), m = b.size(); 8 | int dp[n + 1][m + 1]; 9 | for (int i = 0; i <= n; i++) 10 | { 11 | for (int j = 0; j <= m; j++) 12 | { 13 | if (i == 0 || j == 0) 14 | dp[i][j] = 0; 15 | } 16 | } 17 | for (int i = 1; i <= n; i++) 18 | { 19 | for (int j = 1; j <= m; j++) 20 | { 21 | if (a[i - 1] == b[j - 1]) 22 | { 23 | dp[i][j] = dp[i - 1][j - 1] + 1; 24 | } 25 | else 26 | { 27 | dp[i][j] = max(dp[i - 1][j], dp[i][j - 1]); 28 | } 29 | } 30 | } 31 | int i = n, j = m; 32 | string ans; 33 | while (i != 0 && j != 0) 34 | { 35 | if (a[i - 1] == b[j - 1]) 36 | { 37 | ans += a[i - 1]; 38 | i--; 39 | j--; 40 | } 41 | else 42 | { 43 | if (dp[i][j - 1] > dp[i - 1][j]) 44 | { 45 | j--; 46 | } 47 | else 48 | { 49 | i--; 50 | } 51 | } 52 | } 53 | reverse(ans.begin(), ans.end()); 54 | cout << ans << endl; 55 | return 0; 56 | } -------------------------------------------------------------------------------- /Module 26/lcs_top_down.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | int dp[1005][1005]; 4 | int lcs(string a, int n, string b, int m) 5 | { 6 | if (n == 0 || m == 0) 7 | return 0; 8 | if (dp[n][m] != -1) 9 | return dp[n][m]; 10 | if (a[n - 1] == b[m - 1]) 11 | { 12 | int ans = lcs(a, n - 1, b, m - 1); 13 | return dp[n][m] = ans + 1; 14 | } 15 | else 16 | { 17 | int ans1 = lcs(a, n - 1, b, m); 18 | int ans2 = lcs(a, n, b, m - 1); 19 | return dp[n][m] = max(ans1, ans2); 20 | } 21 | } 22 | int main() 23 | { 24 | string a, b; 25 | cin >> a >> b; 26 | // memset(dp, -1, sizeof(dp)); 27 | for (int i = 0; i <= a.size(); i++) 28 | { 29 | for (int j = 0; j <= b.size(); j++) 30 | { 31 | dp[i][j] = -1; 32 | } 33 | } 34 | cout << lcs(a, a.size(), b, b.size()); 35 | return 0; 36 | } -------------------------------------------------------------------------------- /Module 26/longest_common_substring.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | int main() 4 | { 5 | string a, b; 6 | cin >> a >> b; 7 | int n = a.size(), m = b.size(); 8 | int dp[n + 1][m + 1]; 9 | for (int i = 0; i <= n; i++) 10 | { 11 | for (int j = 0; j <= m; j++) 12 | { 13 | if (i == 0 || j == 0) 14 | dp[i][j] = 0; 15 | } 16 | } 17 | for (int i = 1; i <= n; i++) 18 | { 19 | for (int j = 1; j <= m; j++) 20 | { 21 | if (a[i - 1] == b[j - 1]) 22 | { 23 | dp[i][j] = dp[i - 1][j - 1] + 1; 24 | } 25 | else 26 | { 27 | dp[i][j] = 0; 28 | } 29 | } 30 | } 31 | int mx = 0; 32 | int ci, cj; 33 | for (int i = 0; i <= n; i++) 34 | { 35 | for (int j = 0; j <= m; j++) 36 | { 37 | if (dp[i][j] > mx) 38 | { 39 | mx = dp[i][j]; 40 | ci = i; 41 | cj = j; 42 | } 43 | } 44 | } 45 | string ans; 46 | while (ci != 0 && cj != 0) 47 | { 48 | if (a[ci - 1] == b[cj - 1]) 49 | { 50 | ans += a[ci - 1]; 51 | ci--; 52 | cj--; 53 | } 54 | else 55 | { 56 | break; 57 | } 58 | } 59 | reverse(ans.begin(), ans.end()); 60 | cout << ans << endl; 61 | return 0; 62 | } -------------------------------------------------------------------------------- /Module 27/.gitignore: -------------------------------------------------------------------------------- 1 | .cph/ 2 | .vscode/ 3 | *.txt 4 | *.exe 5 | *.bin -------------------------------------------------------------------------------- /Module 27/check_string_a_is_subsequence.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | int main() 4 | { 5 | string a, b; 6 | cin >> a >> b; 7 | int n = a.size(), m = b.size(); 8 | // normal O(M) 9 | int x = 0; 10 | bool ans = false; 11 | for (char c : b) 12 | { 13 | if (c == a[x]) 14 | { 15 | x++; 16 | } 17 | if (x == a.size()) 18 | { 19 | ans = true; 20 | break; 21 | } 22 | } 23 | if (ans) 24 | cout << "YES"; 25 | else 26 | cout << "NO"; 27 | 28 | // lcs approach O(N*M) 29 | // int dp[n + 1][m + 1]; 30 | // for (int i = 0; i <= n; i++) 31 | // { 32 | // for (int j = 0; j <= m; j++) 33 | // { 34 | // if (i == 0 || j == 0) 35 | // dp[i][j] = 0; 36 | // } 37 | // } 38 | // for (int i = 1; i <= n; i++) 39 | // { 40 | // for (int j = 1; j <= m; j++) 41 | // { 42 | // if (a[i - 1] == b[j - 1]) 43 | // { 44 | // dp[i][j] = dp[i - 1][j - 1] + 1; 45 | // } 46 | // else 47 | // { 48 | // dp[i][j] = max(dp[i - 1][j], dp[i][j - 1]); 49 | // } 50 | // } 51 | // } 52 | // if (dp[n][m] == a.size()) 53 | // cout << "YES"; 54 | // else 55 | // cout << "NO"; 56 | return 0; 57 | } -------------------------------------------------------------------------------- /Module 27/print_lps.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | int main() 4 | { 5 | string a; 6 | cin >> a; 7 | int n = a.size(); 8 | string b = a; 9 | reverse(b.begin(), b.end()); 10 | int m = b.size(); 11 | 12 | int dp[n + 1][m + 1]; 13 | for (int i = 0; i <= n; i++) 14 | { 15 | for (int j = 0; j <= m; j++) 16 | { 17 | if (i == 0 || j == 0) 18 | dp[i][j] = 0; 19 | } 20 | } 21 | for (int i = 1; i <= n; i++) 22 | { 23 | for (int j = 1; j <= m; j++) 24 | { 25 | if (a[i - 1] == b[j - 1]) 26 | { 27 | dp[i][j] = dp[i - 1][j - 1] + 1; 28 | } 29 | else 30 | { 31 | dp[i][j] = max(dp[i - 1][j], dp[i][j - 1]); 32 | } 33 | } 34 | } 35 | int i = n, j = m; 36 | string ans; 37 | while (i != 0 && j != 0) 38 | { 39 | if (a[i - 1] == b[j - 1]) 40 | { 41 | ans += a[i - 1]; 42 | i--; 43 | j--; 44 | } 45 | else 46 | { 47 | if (dp[i][j - 1] > dp[i - 1][j]) 48 | { 49 | j--; 50 | } 51 | else 52 | { 53 | i--; 54 | } 55 | } 56 | } 57 | reverse(ans.begin(), ans.end()); 58 | cout << ans << endl; 59 | return 0; 60 | } -------------------------------------------------------------------------------- /Module 27/print_shortest_common_supersequence.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | int main() 4 | { 5 | string a, b; 6 | cin >> a >> b; 7 | int n = a.size(); 8 | int m = b.size(); 9 | int dp[n + 1][m + 1]; 10 | for (int i = 0; i <= n; i++) 11 | { 12 | for (int j = 0; j <= m; j++) 13 | { 14 | if (i == 0 || j == 0) 15 | dp[i][j] = 0; 16 | } 17 | } 18 | for (int i = 1; i <= n; i++) 19 | { 20 | for (int j = 1; j <= m; j++) 21 | { 22 | if (a[i - 1] == b[j - 1]) 23 | { 24 | dp[i][j] = dp[i - 1][j - 1] + 1; 25 | } 26 | else 27 | { 28 | dp[i][j] = max(dp[i - 1][j], dp[i][j - 1]); 29 | } 30 | } 31 | } 32 | int i = n, j = m; 33 | string ans; 34 | while (i != 0 && j != 0) 35 | { 36 | if (a[i - 1] == b[j - 1]) 37 | { 38 | ans += a[i - 1]; 39 | i--; 40 | j--; 41 | } 42 | else if (dp[i - 1][j] > dp[i][j - 1]) 43 | { 44 | ans += a[i - 1]; 45 | i--; 46 | } 47 | else 48 | { 49 | ans += b[j - 1]; 50 | j--; 51 | } 52 | } 53 | while (i != 0) 54 | { 55 | ans += a[i - 1]; 56 | i--; 57 | } 58 | while (j != 0) 59 | { 60 | ans += b[j - 1]; 61 | j--; 62 | } 63 | reverse(ans.begin(), ans.end()); 64 | cout << ans << endl; 65 | return 0; 66 | } -------------------------------------------------------------------------------- /Module 27/shortest_common_supersequence.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | using namespace std; 3 | int main() 4 | { 5 | string a, b; 6 | cin >> a >> b; 7 | int n = a.size(); 8 | int m = b.size(); 9 | int dp[n + 1][m + 1]; 10 | for (int i = 0; i <= n; i++) 11 | { 12 | for (int j = 0; j <= m; j++) 13 | { 14 | if (i == 0 || j == 0) 15 | dp[i][j] = 0; 16 | } 17 | } 18 | for (int i = 1; i <= n; i++) 19 | { 20 | for (int j = 1; j <= m; j++) 21 | { 22 | if (a[i - 1] == b[j - 1]) 23 | { 24 | dp[i][j] = dp[i - 1][j - 1] + 1; 25 | } 26 | else 27 | { 28 | dp[i][j] = max(dp[i - 1][j], dp[i][j - 1]); 29 | } 30 | } 31 | } 32 | cout << n + m - dp[n][m] << endl; 33 | return 0; 34 | } --------------------------------------------------------------------------------