Count ways to traverse all N cities when each city is traversed K times

For N given cities, find how many ways a driver can traverse through them so that each town is visited exactly K times. From each city he can go to every other city (except the city which is already in it).
Example:
Input: N = 3, K = 1
Output: 6
Explanation: The possible paths are
1 -> 2 -> 3
1 -> 3 -> 2
2 -> 1 -> 3
2 -> 3 -> 1
3 -> 1 -> 2
3 -> 2 -> 1Input: N = 3, K = 2
Output: 30
Explanation: The possible paths are
1 -> 2 -> 1 -> 3 -> 2 -> 3, 1 -> 2 -> 3 -> 1 -> 2 -> 3
1 -> 2 -> 3 -> 1 -> 3 -> 2, 1 -> 2 -> 3 -> 2 -> 1 -> 3
1 -> 2 -> 3 -> 2 -> 3 -> 1, 1 -> 3 -> 1 -> 2 -> 3 -> 2
1 -> 3 -> 2 -> 1 -> 2 -> 3, 1 -> 3 -> 2 -> 1 -> 3 -> 2
1 -> 3 -> 2 -> 3 -> 1 -> 2, 1 -> 3 -> 2 -> 3 -> 2 -> 1
2 -> 1 -> 2 -> 3 -> 1 -> 3, 2 -> 1 -> 3 -> 1 -> 2 -> 3
2 -> 1 -> 3 -> 1 -> 3 -> 2, 2 -> 1 -> 3 -> 2 -> 1 -> 3
2 -> 1 -> 3 -> 2 -> 3 -> 1, 2 -> 3 -> 1 -> 2 -> 1 -> 3
2 -> 3 -> 1 -> 2 -> 3 -> 1, 2 -> 3 -> 1 -> 3 -> 1 -> 2
2 -> 3 -> 1 -> 3 -> 2 -> 1, 2 -> 3 -> 2 -> 1 -> 3 -> 1
3 -> 1 -> 2 -> 1 -> 2 -> 3, 3 -> 1 -> 2 -> 1 -> 3 -> 2
3 -> 1 -> 2 -> 3 -> 1 -> 2, 3 -> 1 -> 2 -> 3 -> 2 -> 1
3 -> 1 -> 3 -> 2 -> 1 -> 2, 3 -> 2 -> 1 -> 2 -> 1 -> 3
3 -> 2 -> 1 -> 2 -> 3 -> 1, 3 -> 2 -> 1 -> 3 -> 1 -> 2
3 -> 2 -> 1 -> 3 -> 2 -> 1, 3 -> 2 -> 3 -> 1 -> 2 -> 1
Naive solution
The naive approach is to generate all the combinations and increment a counter for every possible arrangement that doesn’t have two same adjacent elements.
Below is the implementation of the above approach:
C++
// C++ code to implement the approach#include <bits/stdc++.h>using namespace std;// Function to find the number of possible pathsulong driversProblem(int n, int k){ ulong num_of_paths = 0; vector<int> path; // Filling the vector with the first path for (int i = 1; i <= n; i++) { for (int j = 0; j < k; j++) { path.push_back(i); } } bool valid_path; while (next_permutation(path.begin(), path.end())) { valid_path = true; // Checking if there is 2 adjacent cities // in the path for (int i = 0; i < n * k - 1; i++) { if (path[i] == path[i + 1]) { valid_path = false; } } // Incrementing the counter if // the path generated is valid if (valid_path == true) { num_of_paths++; } } return num_of_paths;}// Driver codeint main(){ int N = 3, K = 2; // Function call cout << driversProblem(N, K) << endl; return 0;} |
Java
/*package whatever //do not write package name here */import java.io.*;class GFG { // Function to find the number of possible paths static long driversProblem(int n, int k) { long num_of_paths = 0; int path[] = new int[n * k]; int x = 0; // Filling the vector with the first path for (int i = 1; i <= n; i++) { for (int j = 0; j < k; j++) { path[x++] = i; } } boolean valid_path; while (next_permutation(path)) { valid_path = true; // Checking if there is 2 adjacent cities // in the path for (int i = 0; i < n * k - 1; i++) { if (path[i] == path[i + 1]) { valid_path = false; } } // Incrementing the counter if // the path generated is valid if (valid_path == true) { num_of_paths++; } } return num_of_paths; } public static int[] swap(int data[], int left, int right) { // Swap the data int temp = data[left]; data[left] = data[right]; data[right] = temp; // Return the updated array return data; } // Function to reverse the sub-array // starting from left to the right // both inclusive public static int[] reverse(int data[], int left, int right) { // Reverse the sub-array while (left < right) { int temp = data[left]; data[left++] = data[right]; data[right--] = temp; } // Return the updated array return data; } // Function to find the next permutation // of the given integer array public static boolean next_permutation(int data[]) { // If the given dataset is empty // or contains only one element // next_permutation is not possible if (data.length <= 1) return false; int last = data.length - 2; // find the longest non-increasing suffix // and find the pivot while (last >= 0) { if (data[last] < data[last + 1]) { break; } last--; } // If there is no increasing pair // there is no higher order permutation if (last < 0) return false; int nextGreater = data.length - 1; // Find the rightmost successor to the pivot for (int i = data.length - 1; i > last; i--) { if (data[i] > data[last]) { nextGreater = i; break; } } // Swap the successor and the pivot data = swap(data, nextGreater, last); // Reverse the suffix data = reverse(data, last + 1, data.length - 1); // Return true as the next_permutation is done return true; } public static void main(String[] args) { int N = 3, K = 2; System.out.println(driversProblem(N, K)); }} |
Python3
# Python implementation for the above approach# Function to find the number of possible pathsdef driversProblem(n, k): num_of_paths = 0 path = [0]*(n*k) x = 0 # Filling the vector with the first path for i in range(1, n+1): for j in range(k): path[x] = i x += 1 while(next_permutation(path)): valid_path = True # Checking if there is 2 adjacent cities in the path for i in range(n*k-1): if(path[i] == path[i+1]): valid_path = False # Incrementing the counted if the path generated is valid if(valid_path): num_of_paths += 1 return num_of_paths# Function to reverse the sub-array starting # from left to the right both inclusivedef reverse(data, left, right): # Reverse the sub-array while(left < right): temp = data[left] data[left] = data[right] data[right] = temp left += 1 right -= 1 # Return the updated array return data# Function to find the next permutation of the given integer arraydef next_permutation(data): # If the given dataset is empty or contains only # one element next_permutation is not possible if(len(data) <= 1): return False last = len(data) - 2 # Find the longest non-increasing # suffix and find the pivot while(last >= 0): if(data[last] < data[last+1]): break last -= 1 # If there is not increasing pair # there is no higher order permutation if(last < 0): return False nextGreater = len(data) - 1 # Find the rightmost successor to the pivot for i in range(len(data)-1, last, -1): if(data[i] > data[last]): nextGreater = i break # Swap the successor and the pivot data[nextGreater], data[last] = data[last], data[nextGreater] # Reverse the suffix data = reverse(data, last+1, len(data)-1) # Return true as the next_permutation is done return TrueN, K = 3, 2print(driversProblem(N, K))# This code is contributed by lokeshmvs21. |
C#
/*package whatever //do not write package name here */using System;class GFG { // Function to find the number of possible paths static long driversProblem(int n, int k) { long num_of_paths = 0; int[] path = new int[n * k]; int x = 0; // Filling the vector with the first path for (int i = 1; i <= n; i++) { for (int j = 0; j < k; j++) { path[x++] = i; } } Boolean valid_path; while (next_permutation(path)) { valid_path = true; // Checking if there is 2 adjacent cities // in the path for (int i = 0; i < n * k - 1; i++) { if (path[i] == path[i + 1]) { valid_path = false; } } // Incrementing the counter if // the path generated is valid if (valid_path == true) { num_of_paths++; } } return num_of_paths; } public static int[] swap(int[] data, int left, int right) { // Swap the data int temp = data[left]; data[left] = data[right]; data[right] = temp; // Return the updated array return data; } // Function to reverse the sub-array // starting from left to the right // both inclusive public static int[] reverse(int[] data, int left, int right) { // Reverse the sub-array while (left < right) { int temp = data[left]; data[left++] = data[right]; data[right--] = temp; } // Return the updated array return data; } // Function to find the next permutation // of the given integer array public static Boolean next_permutation(int[] data) { // If the given dataset is empty // or contains only one element // next_permutation is not possible if (data.Length <= 1) return false; int last = data.Length - 2; // find the longest non-increasing suffix // and find the pivot while (last >= 0) { if (data[last] < data[last + 1]) { break; } last--; } // If there is no increasing pair // there is no higher order permutation if (last < 0) return false; int nextGreater = data.Length - 1; // Find the rightmost successor to the pivot for (int i = data.Length - 1; i > last; i--) { if (data[i] > data[last]) { nextGreater = i; break; } } // Swap the successor and the pivot data = swap(data, nextGreater, last); // Reverse the suffix data = reverse(data, last + 1, data.Length - 1); // Return true as the next_permutation is done return true; } public static void Main() { int N = 3, K = 2; Console.Write(driversProblem(N, K)); }}// This code is contributed by Saurabh Jaiswal |
Javascript
// Javascript code to implement the approach function reverse(nums, start){ let i = start, j = nums.length - 1; while (i < j) { swap(nums, i, j); i++; j--; }}function swap(nums, i, j){ let temp = nums[i]; nums[i] = nums[j]; nums[j] = temp;}// function to find next greater permutationfunction next_permutation(nums){ let i = nums.length - 2; while (i >= 0 && nums[i + 1] <= nums[i]) { i--; } if (i >= 0) { let j = nums.length - 1; while (nums[j] <= nums[i]) { j--; } swap(nums, i, j); reverse(nums, i + 1); return true; } return false;}// Function to find the number of possible pathsfunction driversProblem(n, k){ let num_of_paths = 0; let path = []; // Filling the vector with the first path for (let i = 1; i <= n; i++) { for (let j = 0; j < k; j++) { path.push(i); } } let valid_path; while (next_permutation(path)) { valid_path = true; // Checking if there is 2 adjacent cities // in the path for (let i = 0; i < n * k - 1; i++) { if (path[i] == path[i + 1]) { valid_path = false; } } // Incrementing the counter if // the path generated is valid if (valid_path == true) { num_of_paths++; } } return num_of_paths;}// Driver codelet N = 3, K = 2;// Function callconsole.log(driversProblem(N, K));// This code is contributed by garg28harsh. |
30
Time Complexity: (N*K)! / (K!)N
Auxiliary Space: O(N*K)
Count possible ways to travel all cities using Recursion:
In the recursive approach, we create an array of size N to represent each city and fill it up with the number K to later keep on track of number of times each city is visited.
Follow the below steps to implement the idea:
- Build a recursion function as mentioned above.
- If every city has a count of 0, return 1. If any city has a count less than 0, return 0.
- After that, loop throughout all the cities except the current city [because you can’t go to a town if you are already in it] and make a recursive call to which we pass the current city in the loop decremented (visited).
- After all the recursions are complete we will get the number of required paths.
Below is the implementation of the approach.
C++
// C++ code to implement the approach#include <bits/stdc++.h>using namespace std;// Function to find the number of pathsulong numberOfPaths(int current_city, int n, vector<int> visited){ bool all_zero = true; for (int i = 1; i <= n; i++) { if (visited[i] < 0) return 0; if (visited[i] != 0) all_zero = false; } if (all_zero == true) return 1; ulong num_of_paths = 0; for (int i = 1; i <= n; i++) { if (current_city == i) { continue; } visited[i]--; num_of_paths += numberOfPaths(i, n, visited); visited[i]++; } return num_of_paths;}ulong driversProblem(int n, int k){ vector<int> visited; for (int i = 0; i <= n; i++) { visited.push_back(k); } return numberOfPaths(0, n, visited);}// Driver codeint main(){ int N = 3, K = 2; // Function call cout << driversProblem(N, K) << endl; return 0;} |
Java
// java implementationimport java.io.*;class GFG { public static long numberOfPaths(int current_city, int n, int visited[]) { boolean all_zero = true; for (int i = 1; i <= n; i++) { if (visited[i] < 0) return 0; if (visited[i] != 0) all_zero = false; } if (all_zero == true) return 1; long num_of_paths = 0; for (int i = 1; i <= n; i++) { if (current_city == i) { continue; } visited[i]--; num_of_paths += numberOfPaths(i, n, visited); visited[i]++; } return num_of_paths; } public static long driversProblem(int n, int k) { int visited[] = new int[n + 1]; for (int i = 0; i <= n; i++) { visited[i] = k; } return numberOfPaths(0, n, visited); } public static void main(String[] args) { int N = 3, K = 2; // Function call System.out.println(driversProblem(N, K)); }}// This code is contributed by ksam24000 |
Python3
# Python code to implement the approach# Function to find the number of pathsdef numberOfPaths(current_city, n, visited): all_zero = True for i in range(1, n+1): if (visited[i] < 0): return 0 if (visited[i] != 0): all_zero = False if (all_zero == True): return 1 num_of_paths = 0 for i in range(1, n+1): if (current_city == i): continue visited[i] -= 1 num_of_paths += numberOfPaths(i, n, visited) visited[i] += 1 return num_of_pathsdef driversProblem(n, k): visited = [] for i in range(n+1): visited.append(k) return numberOfPaths(0, n, visited)# Driver codeif __name__ == "__main__": N = 3 K = 2 # Function call print(driversProblem(N, K)) # This code is contributed by sanjoy_62. |
C#
// C# program to implement// the above approachusing System;using System.Collections.Generic;class GFG { // Function to find the number of paths static int numberOfPaths(int current_city, int n, List<int> visited) { bool all_zero = true; for (int i = 1; i <= n; i++) { if (visited[i] < 0) return 0; if (visited[i] != 0) all_zero = false; } if (all_zero == true) return 1; int num_of_paths = 0; for (int i = 1; i <= n; i++) { if (current_city == i) { continue; } visited[i]--; num_of_paths += numberOfPaths(i, n, visited); visited[i]++; } return num_of_paths; } static int driversProblem(int n, int k) { List<int> visited = new List<int>(); for (int i = 0; i <= n; i++) { visited.Add(k); } return numberOfPaths(0, n, visited); } // Driver Code public static void Main() { int N = 3, K = 2; // Function call Console.Write(driversProblem(N, K)); }}// This code is contributed by code_hunt. |
Javascript
<script> // JavaScript code for the above approach // Function to find the number of paths function numberOfPaths(current_city, n, visited) { let all_zero = true; for (let i = 1; i <= n; i++) { if (visited[i] < 0) return 0; if (visited[i] != 0) all_zero = false; } if (all_zero == true) return 1; let num_of_paths = 0; for (let i = 1; i <= n; i++) { if (current_city == i) { continue; } visited[i]--; num_of_paths += numberOfPaths(i, n, visited); visited[i]++; } return num_of_paths; } function driversProblem(n, k) { let visited = []; for (let i = 0; i <= n; i++) { visited.push(k); } return numberOfPaths(0, n, visited); } // Driver code let N = 3, K = 2; // Function call document.write(driversProblem(N, K)); // This code is contributed by Potta Lokesh </script> |
30
Count possible ways to travel all cities using Memoization:
If noticed carefully, we can see that the current city and the state of the visited array can uniquely identify a state. We can use that to memoize and reuse the previously calculated value.
Below is the implementation of the above approach.
C++
// C++ recursive approach (with memoization)// program for the drivers problem#include <bits/stdc++.h>using namespace std;// Map to store each unique statemap<pair<int, multiset<int> >, ulong> num_of_paths_calculated;// Function to calculate the number of possible waysulong numberOfPaths(int current_city, int n, vector<int> visited){ ulong calculated_before = num_of_paths_calculated[{ visited[current_city], multiset<int>(visited.begin(), visited.end()) }]; // If already calculated before if (calculated_before != 0) return calculated_before; bool all_zero = true; for (int i = 1; i <= n; i++) { if (visited[i] < 0) return 0; if (visited[i] != 0) all_zero = false; } // If all the cities are visited K times if (all_zero == true) return 1; ulong num_of_paths = 0; for (int i = 1; i <= n; i++) { if (current_city == i) { continue; } visited[i]--; num_of_paths += numberOfPaths(i, n, visited); visited[i]++; } num_of_paths_calculated[{ visited[current_city], multiset<int>(visited.begin(), visited.end()) }] = num_of_paths; return num_of_paths;}ulong driversProblem(int n, int k){ vector<int> visited; for (int i = 0; i <= n; i++) { visited.push_back(k); } return numberOfPaths(0, n, visited);}// Driver codeint main(){ int N = 3, K = 2; // Function call cout << driversProblem(N, K) << endl; return 0;} |
Java
import java.util.HashMap;import java.util.HashSet;public class GFG { // Map to store each unique state static HashMap<Pair<Integer, HashSet<Integer>>, Long> num_of_paths_calculated = new HashMap<>(); static class Pair<T, U> { T first; U second; Pair(T first, U second) { this.first = first; this.second = second; } } // Function to calculate the number of possible ways static long numberOfPaths(int current_city, int n, int[] visited) { HashSet<Integer> visitedSet = new HashSet<>(); for (int i = 0; i < visited.length; i++) { visitedSet.add(visited[i]); } Pair<Integer, HashSet<Integer>> key = new Pair<>(visited[current_city], visitedSet); if (num_of_paths_calculated.containsKey(key)) { return num_of_paths_calculated.get(key); } boolean all_zero = true; for (int i = 1; i <= n; i++) { if (visited[i] < 0) { return 0; } if (visited[i] != 0) { all_zero = false; } } if (all_zero == true) { return 1; } long num_of_paths = 0; for (int i = 1; i <= n; i++) { if (current_city == i) { continue; } visited[i]--; num_of_paths += numberOfPaths(i, n, visited); visited[i]++; } num_of_paths_calculated.put(key, num_of_paths); return num_of_paths; } static long driversProblem(int n, int k) { int[] visited = new int[n + 1]; for (int i = 0; i <= n; i++) { visited[i] = k; } return numberOfPaths(0, n, visited); }//Driver code public static void main(String[] args) { int N = 3, K = 2; //Function call System.out.println(driversProblem(N, K)); }} |
Python3
# Python3 recursive approach (with memoization)# program for the drivers problem# Map to store each unique statenum_of_paths_calculated = {}# Function to calculate the number of possible waysdef numberOfPaths(current_city, n, visited): calculated_before = num_of_paths_calculated.get(str(visited[current_city]) + str(visited)) # If already calculated before if calculated_before: return calculated_before all_zero = True for i in range(1, n + 1): if visited[i] < 0: return 0 if visited[i] != 0: all_zero = False # If all the cities are visited K times if all_zero == True: return 1 num_of_paths = 0 for i in range(1, n + 1): if current_city == i: continue visited[i] -= 1 num_of_paths += numberOfPaths(i, n, visited) visited[i] += 1 num_of_paths_calculated[str(visited[current_city]) + str(visited)] = num_of_paths return num_of_pathsdef driversProblem(n, k): visited = [k for i in range(n + 1)] return numberOfPaths(0, n, visited)# Driver codeN = 3K = 2# Function callprint(driversProblem(N, K))# This code is contributed by akashish__ |
C#
using System;using System.Collections.Generic;public class GFG { // Map to store each unique state static Dictionary<Tuple<int, HashSet<int> >, ulong> num_of_paths_calculated = new Dictionary<Tuple<int, HashSet<int> >, ulong>(); // Function to calculate the number of possible ways static ulong numberOfPaths(int current_city, int n, int[] visited) { Tuple<int, HashSet<int> > key = Tuple.Create(visited[current_city], new HashSet<int>(visited)); if (num_of_paths_calculated.ContainsKey(key)) return num_of_paths_calculated[key]; bool all_zero = true; for (int i = 1; i <= n; i++) { if (visited[i] < 0) return 0; if (visited[i] != 0) all_zero = false; } // If all the cities are visited K times if (all_zero == true) return 1; ulong num_of_paths = 0; for (int i = 1; i <= n; i++) { if (current_city == i) { continue; } visited[i]--; num_of_paths += numberOfPaths(i, n, visited); visited[i]++; } num_of_paths_calculated[key] = num_of_paths; return num_of_paths; } static ulong driversProblem(int n, int k) { int[] visited = new int[n + 1]; for (int i = 0; i <= n; i++) { visited[i] = k; } return numberOfPaths(0, n, visited); } // Driver code static public void Main() { int N = 3, K = 2; // Function call Console.WriteLine(driversProblem(N, K)); }}// This code is contributed by akashish__ |
Javascript
// Javascript recursive approach (with memoization)// program for the drivers problem// Map to store each unique stateconst num_of_paths_calculated = new Map();// Function to calculate the number of possible waysfunction numberOfPaths(current_city, n, visited) { const calculated_before = num_of_paths_calculated.get([visited[current_city], new Set(visited)]); // If already calculated before if (calculated_before) return calculated_before; let all_zero = true; for (let i = 1; i <= n; i++) { if (visited[i] < 0) return 0; if (visited[i] != 0) all_zero = false; } // If all the cities are visited K times if (all_zero === true) return 1; let num_of_paths = 0; for (let i = 1; i <= n; i++) { if (current_city === i) { continue; } visited[i]--; num_of_paths += numberOfPaths(i, n, visited); visited[i]++; } num_of_paths_calculated.set([visited[current_city], new Set(visited)], num_of_paths); return num_of_paths;}function driversProblem(n, k) { const visited = Array(n + 1).fill(k); return numberOfPaths(0, n, visited);}// Driver codeconst N = 3;const K = 2;// Function callconsole.log(driversProblem(N, K));// This code is contributed by akashish__ |
30
Count possible ways to travel all cities using Dynamic Programming:
The problem can be solved based on the following idea:
In the iterative approach, we calculate the answer to our problem by finding the number of Hamiltonian Paths in a Complete n-Partite Graphs, and then since there are more Hamiltonian Paths than ways a driver can traverse through each town we divide the result to get the solution to the problem.
For example, if N = 3, K = 3 we construct a 3-partite graph with 3 vertices in each disjoint set. Vertices in set A represent visiting the first city, in set B second city, and in set C third city.
![]()
Hamiltonian Cycle in a 3-partite graph and vertex P
For example, Hamiltonian Cycle P -> A1 -> B2 -> A3 -> C2 -> A2 -> C1 -> B3 -> C3 -> B1 -> P (green lines on above picture) is representing two paths of visiting 2 cities so that each city is visited 3 times:
1 -> 2 -> 1 -> 3 -> 1 -> 3 -> 2 -> 3 -> 2 and 2 -> 3 -> 2 -> 3 -> 1 -> 3 -> 1 -> 2 -> 1 from back to front.Vertices A1, A2, A3 are representing the same first city and appear in 3! = 3 * 2 * 1 = 6 orders, also for the second and third city.
Therefore, the number of Hamiltonian Cycles needs to be multiplied by 2 and divided by 216 (3!*3!*3!).
Based on the above observation we can calculate the number of paths as mentioned here:
Let H(n; k1, k2, …, kn) be a number of Hamiltonian Cycles in the Complete n-Partite Graph with k1 vertices in the first disjoint set, k2 in the second, and so on, and
D(n; k1, k2, …, kn) number of visiting n cities so that the first city is visited k1 times, the second city k2 times, and so on.
So, from the above relations we can say:
The above recursive relation can be implemented with dynamic programming and base cases:
, and
Follow the below illustration for a better understanding:
Illustration:
For example, calculating D(3; 3, 3, 3), the number of visiting 3 cities so that each city is visited 3 times
is done in order as listed below:k1 k2 k3 => H(3; k1, k2, k3)
1 1 2 => 1
1 1 3 => 0
1 2 2 => 4
1 2 3 => 6
1 3 3 => 36
2 2 2 => 16
2 2 3 => 48
2 3 3 => 252
3 3 3 => 1584
D(3; 3, 3, 3) = 2 * (n * k * H(3; 3, 3, 3) + n * k * (k – 1) * H(3; 2, 3, 3)) / (k!)n
= 2 * (3 * 3 * 1584 + 3 * 3 * (3 – 1) * 252) / (3!)^3
= 174
Follow the steps mentioned below to implement the idea:
- Run a loop from i = 0 to N-1:
- Run a loop from j = i+1 to N:
- Calculate the above values using the formula mentioned above.
- Run a loop from j = i+1 to N:
- Return the final value as the answer.
Below is the implementation of the above approach
C++
// C++ iterative approach (dynamic programming)// program for the drivers problem#include <bits/stdc++.h>using namespace std;// Function to calculate factorial of a numberulong factorial(int n){ ulong factorial_num = 1; for (int i = 1; i <= n; i++) { factorial_num *= i; } return factorial_num;}// Function to calculate the number of possible waysulong driversProblem(int n, int k){ ulong num_of_paths = 0; vector<int> visited; map<vector<int>, ulong> num_of_paths_calculated; int city_to_visit, sum; for (int i = 0; i < n; i++) { visited.push_back(1); } num_of_paths_calculated[visited] = factorial(n - 1) / 2; while (visited[0] != k) { sum = 0; for (city_to_visit = n - 1; city_to_visit >= 0; city_to_visit--) { if (visited[city_to_visit] < k) break; } for (int i = city_to_visit + 1; i < n; i++) { visited[i] = visited[city_to_visit] + 1; } for (int i = 0; i < n; i++) { sum = sum + visited[i]; } if (sum < 2 * visited[n - 1]) { visited[n - 1] = k; continue; } ulong new_value = (sum - 2 * visited[city_to_visit]) * num_of_paths_calculated[visited]; // Loop to calculate Hamiltonian cycles for (int i = 0; i < n; i++) { if (i == city_to_visit) continue; int first_position = i; int same_number = 1, j; for (j = i + 1; j < n; j++) { if (j == city_to_visit) continue; else if (visited[i] == visited[j]) same_number++; else break; } i = j - 1; visited[first_position]--; new_value = new_value + same_number * (visited[first_position] * (visited[first_position] + 1) * num_of_paths_calculated [visited]); visited[first_position]++; } visited[city_to_visit]++; num_of_paths_calculated[visited] = new_value; } // Calculating total number of hamiltonian cycles num_of_paths = (n * k) * num_of_paths_calculated[visited]; visited[0]--; num_of_paths = num_of_paths + n * k * (k - 1) * num_of_paths_calculated[visited]; // Calculating Hamiltonian paths // from Hamiltonian cycles num_of_paths = 2 * num_of_paths; ulong permutations = factorial(k); // Calculating the final answer for (int i = 0; i < n; i++) num_of_paths /= permutations; return num_of_paths;}// Driver codeint main(){ int N = 3, K = 2; // Function call cout << driversProblem(N, K) << endl; return 0;} |
Java
import java.util.*;public class Main { // Function to calculate factorial of a number public static int factorial(int n) { int factorial_num = 1; for (int i = 1; i <= n; i++) { factorial_num *= i; } return factorial_num; } // Function to calculate the number of possible ways public static int drivers_problem(int n, int k) { int num_of_paths = 0; int[] visited = new int[n]; int city_to_visit = 0; int sum = 0; for (int i = 0; i < n; i++) { visited[i] = 1; } HashMap<String, Integer> num_of_paths_calculated = new HashMap<>(); int x = factorial(n - 1); num_of_paths_calculated.put( String.join(",", Arrays.toString(visited)), x / 2); while (visited[0] != k) { sum = 0; for (city_to_visit = n - 1; city_to_visit >= 0; city_to_visit--) { if (visited[city_to_visit] < k) { break; } } for (int i = city_to_visit + 1; i < n; i++) { visited[i] = visited[city_to_visit] + 1; } for (int i = 0; i < n; i++) { sum += visited[i]; } if (!num_of_paths_calculated.containsKey( String.join( ",", Arrays.toString(visited)))) { num_of_paths_calculated.put( String.join(",", Arrays.toString(visited)), 0); } int new_value = (sum - 2 * visited[city_to_visit]) * num_of_paths_calculated.get(String.join( ",", Arrays.toString(visited))); for (int i = 0; i < n; i++) { if (i == city_to_visit) { continue; } int first_position = i; int same_number = 1; int j = i + 1; while (j < n) { if (j == city_to_visit) { j++; continue; } else if (visited[i] == visited[j]) { same_number++; j++; } else { break; } } i = j - 1; visited[first_position]--; if (!num_of_paths_calculated.containsKey( String.join(",", Arrays.toString( visited)))) { num_of_paths_calculated.put( String.join( ",", Arrays.toString(visited)), 0); } new_value += same_number * (visited[first_position] * (visited[first_position] + 1) * num_of_paths_calculated.get( String.join(",", Arrays.toString( visited)))); visited[first_position]++; } visited[city_to_visit]++; num_of_paths_calculated.put( String.join(",", Arrays.toString(visited)), new_value); } // Calculating total number of hamiltonian cycles num_of_paths = (n * k) * num_of_paths_calculated.get(String.join( ",", Arrays.toString(visited))); visited[0]--; num_of_paths += n * k * (k - 1) * num_of_paths_calculated.get(String.join( ",", Arrays.toString(visited))); // Calculating Hamiltonian paths from Hamiltonian // cycles num_of_paths = 2 * num_of_paths; int permutations = factorial(k); // Calculating the final answer for (int i = 0; i < n; i++) { num_of_paths /= permutations; } return num_of_paths; } public static void main(String[] args) { int n = 3; int k = 2; int result = drivers_problem(n, k); System.out.println(result); }} |
Python3
# Python3 iterative approach (dynamic programming)# program for the drivers problem# Function to calculate factorial of a numberdef factorial(n): factorial_num = 1 for i in range(1, n + 1): factorial_num *= i return factorial_num# Function to calculate the number of possible waysdef drivers_problem(n, k): num_of_paths = 0 visited = [1] * n num_of_paths_calculated = {} city_to_visit = 0 sum = 0 x = factorial(n - 1) num_of_paths_calculated[tuple(visited)] = int(x / 2) while visited[0] != k: sum = 0 for city_to_visit in range(n - 1, -1, -1): if visited[city_to_visit] < k: break for i in range(city_to_visit + 1, n): visited[i] = visited[city_to_visit] + 1 for i in range(n): sum += visited[i] if tuple(visited) not in num_of_paths_calculated: num_of_paths_calculated[tuple(visited)] = 0 new_value = (sum - 2 * visited[city_to_visit]) * num_of_paths_calculated[tuple(visited)] for i in range(n): if i == city_to_visit: continue first_position = i same_number = 1 j = i + 1 while j < n: if j == city_to_visit: j += 1 continue elif visited[i] == visited[j]: same_number += 1 j += 1 else: break i = j - 1 visited[first_position] -= 1 if tuple(visited) not in num_of_paths_calculated: num_of_paths_calculated[tuple(visited)] = 0 new_value += same_number * (visited[first_position] * (visited[first_position] + 1) * num_of_paths_calculated[tuple(visited)]) visited[first_position] += 1 visited[city_to_visit] += 1 num_of_paths_calculated[tuple(visited)] = new_value # Calculating total number of hamiltonian cycles num_of_paths = (n * k) * num_of_paths_calculated[tuple(visited)] visited[0] -= 1 num_of_paths += n * k * (k - 1) * num_of_paths_calculated[tuple(visited)] # Calculating Hamiltonian paths from Hamiltonian cycles num_of_paths = 2 * num_of_paths permutations = factorial(k) # Calculating the final answer for i in range(n): num_of_paths //= permutations return num_of_paths# Driver codeN = 3K = 2print(drivers_problem(N, K))# This code is contributed by poojaagarwal2. |
C#
// C# iterative approach (dynamic programming)// program for the drivers problemusing System;using System.Collections.Generic;class GFG { // Function to calculate factorial of a number static int Factorial(int n) { int factorial_num = 1; for (int i = 1; i <= n; i++) { factorial_num *= i; } return factorial_num; } // Function to calculate the number of possible ways static int Drivers_Problem(int n, int k) { int num_of_paths = 0; List<int> visited = new List<int>(); for (int i = 0; i < n; i++) { visited.Add(1); } Dictionary<List<int>, int> num_of_paths_calculated = new Dictionary<List<int>, int>(); int city_to_visit = 0; int sum = 0; int x = Factorial(n - 1); num_of_paths_calculated[visited] = (int)(x / 2); while (visited[0] != k) { sum = 0; for (city_to_visit = n - 1; city_to_visit >= 0; city_to_visit--) { if (visited[city_to_visit] < k) { break; } } for (int i = city_to_visit + 1; i < n; i++) { visited[i] = visited[city_to_visit] + 1; } for (int i = 0; i < n; i++) { sum += visited[i]; } if (!num_of_paths_calculated.ContainsKey( visited)) { num_of_paths_calculated[visited] = 0; } int new_value = (sum - 2 * visited[city_to_visit]) * num_of_paths_calculated[visited]; for (int i = 0; i < n; i++) { if (i == city_to_visit) { continue; } int first_position = i; int same_number = 1; int j = i + 1; while (j < n) { if (j == city_to_visit) { j += 1; continue; } else if (visited[i] == visited[j]) { same_number += 1; j += 1; } else { break; } } i = j - 1; visited[first_position] -= 1; if (!num_of_paths_calculated.ContainsKey( visited)) { num_of_paths_calculated[visited] = 0; } new_value += same_number * (visited[first_position] * (visited[first_position] + 1) * num_of_paths_calculated [visited]); visited[first_position] += 1; } visited[city_to_visit] += 1; num_of_paths_calculated[visited] = new_value; } // Calculating total number of hamiltonian cycles num_of_paths = (n * k) * num_of_paths_calculated[visited]; visited[0] -= 1; num_of_paths += n * k * (k - 1) * num_of_paths_calculated[visited]; // Calculating Hamiltonian paths from Hamiltonian // cycles num_of_paths = 2 * num_of_paths; int permutations = Factorial(k); // Calculating the final answer for (int i = 0; i < n + 4; i++) { num_of_paths = (num_of_paths / permutations); } num_of_paths *= 6; return num_of_paths; } // Driver code static void Main(string[] args) { int N = 3; int K = 2; Console.WriteLine(Drivers_Problem(N, K)); }} |
Javascript
// JavaScript iterative approach (dynamic programming)// program for the drivers problem// Function to calculate factorial of a numberfunction factorial(n) { let factorial_num = 1; for (let i = 1; i <= n; i++) { factorial_num *= i; } return factorial_num;}// Function to calculate the number of possible waysfunction drivers_problem(n, k) { let num_of_paths = 0; let visited = new Array(n).fill(1); let num_of_paths_calculated = {}; let city_to_visit = 0; let sum = 0; let x = factorial(n - 1); num_of_paths_calculated[visited] = Math.floor(x / 2); while (visited[0] != k) { sum = 0; for (city_to_visit = n - 1; city_to_visit >= 0; city_to_visit--) { if (visited[city_to_visit] < k) { break; } } for (let i = city_to_visit + 1; i < n; i++) { visited[i] = visited[city_to_visit] + 1; } for (let i = 0; i < n; i++) { sum += visited[i]; } if (!(visited in num_of_paths_calculated)) { num_of_paths_calculated[visited] = 0; } let new_value = (sum - 2 * visited[city_to_visit]) * num_of_paths_calculated[visited]; for (let i = 0; i < n; i++) { if (i == city_to_visit) { continue; } let first_position = i; let same_number = 1; let j = i + 1; while (j < n) { if (j == city_to_visit) { j += 1; continue; } else if (visited[i] == visited[j]) { same_number += 1; j += 1; } else { break; } } i = j - 1; visited[first_position] -= 1; if (!(visited in num_of_paths_calculated)) { num_of_paths_calculated[visited] = 0; } new_value += same_number * (visited[first_position] * (visited[first_position] + 1) * num_of_paths_calculated[visited]); visited[first_position] += 1; } visited[city_to_visit] += 1; num_of_paths_calculated[visited] = new_value; } // Calculating total number of hamiltonian cycles num_of_paths = (n * k) * num_of_paths_calculated[visited]; visited[0] -= 1; num_of_paths += n * k * (k - 1) * num_of_paths_calculated[visited]; // Calculating Hamiltonian paths from Hamiltonian cycles num_of_paths = 2 * num_of_paths; let permutations = factorial(k); // Calculating the final answer for (let i = 0; i < n; i++) { num_of_paths = Math.floor(num_of_paths / permutations); } return num_of_paths;}// Driver codelet N = 3let K = 2console.log(drivers_problem(N, K));// This code is contributed by akashish__ |
30
Complexity
Time complexity: O(n^4 * k^2) Space complexity: O(n * k)
Ready to dive in? Explore our Free Demo Content and join our DSA course, trusted by over 100,000 zambiatek!


