При дадени n приятели всеки може да остане сам или може да се свърже с друг приятел. Всеки приятел може да бъде сдвоен само веднъж. Разберете общия брой начини, по които приятелите могат да останат необвързани или да се сдвоят.
Примери:
Input : n = 3 Output : 4 Explanation: {1} {2} {3} : all single {1} {2 3} : 2 and 3 paired but 1 is single. {1 2} {3} : 1 and 2 are paired but 3 is single. {1 3} {2} : 1 and 3 are paired but 2 is single. Note that {1 2} and {2 1} are considered same. Mathematical Explanation: The problem is simplified version of how many ways we can divide n elements into multiple groups. (here group size will be max of 2 elements). In case of n = 3 we have only 2 ways to make a group: 1) all elements are individual(111) 2) a pair and individual (21) In case of n = 4 we have 3 ways to form a group: 1) all elements are individual (1111) 2) 2 individuals and one pair (211) 3) 2 separate pairs (22) tinytextbf{Математическа формула:} нов ред{frac{n!}{((g_1!)^xtimes (g_2!)^ytimes ... (g_n!)^z)times(x!times y!times...z!)}}spacespacetinytext{ ----- (1)} нов ред{minytext{ако същият размер на групата се повтаря xy...z пъти, трябва да разделим допълнително нашия отговор на x!y!...z!}} нов ред{малък текст{сега нека разгледаме нашия случай n=3 и максимален размер на групата от размер 2 и минимален размер 1:}} нов ред{frac{3!}{(1!)^3times(3!)} интервал+интервал frac{3!}{(2!)^1times(1!)^1times(1!)^2}space = 4} нов ред{текст{сега нека разгледаме нашия случай n=4:}} нов ред{frac{4!}{(1!)^4times(4!)} space+ frac{4!}{(2!)^1times(1!)^2times(2!)}space + space frac{4!}{(2!)^2times(2!)}space = 10}
Препоръчителна практика Проблем със сдвояването на приятели Опитайте!
За n-тото лице има два избора: 1) n-тото лице остава необвързано, повтаряме за f(n - 1)2) n-тото лице се сдвоява с който и да е от останалите n - 1 лица. Получаваме (n - 1) * f(n - 2) Следователно можем рекурсивно да запишем f(n) като:f(n) = f(n - 1) + (n - 1) * f(n - 2)
Тъй като горната рекурсивна формула има припокриващи се подпроблеми можем да го решим с помощта на динамично програмиране.
C++// C++ program for solution of // friends pairing problem #include using namespace std; // Returns count of ways n people // can remain single or paired up. int countFriendsPairings(int n) { int dp[n + 1]; // Filling dp[] in bottom-up manner using // recursive formula explained above. for (int i = 0; i <= n; i++) { if (i <= 2) dp[i] = i; else dp[i] = dp[i - 1] + (i - 1) * dp[i - 2]; } return dp[n]; } // Driver code int main() { int n = 4; cout << countFriendsPairings(n) << endl; return 0; }
Java // Java program for solution of // friends pairing problem import java.io.*; class GFG { // Returns count of ways n people // can remain single or paired up. static int countFriendsPairings(int n) { int dp[] = new int[n + 1]; // Filling dp[] in bottom-up manner using // recursive formula explained above. for (int i = 0; i <= n; i++) { if (i <= 2) dp[i] = i; else dp[i] = dp[i - 1] + (i - 1) * dp[i - 2]; } return dp[n]; } // Driver code public static void main(String[] args) { int n = 4; System.out.println(countFriendsPairings(n)); } } // This code is contributed by vt_m
Python3 # Python program solution of # friends pairing problem # Returns count of ways # n people can remain # single or paired up. def countFriendsPairings(n): dp = [0 for i in range(n + 1)] # Filling dp[] in bottom-up manner using # recursive formula explained above. for i in range(n + 1): if(i <= 2): dp[i] = i else: dp[i] = dp[i - 1] + (i - 1) * dp[i - 2] return dp[n] # Driver code n = 4 print(countFriendsPairings(n)) # This code is contributed # by Soumen Ghosh.
C# // C# program solution for // friends pairing problem using System; class GFG { // Returns count of ways n people // can remain single or paired up. static int countFriendsPairings(int n) { int[] dp = new int[n + 1]; // Filling dp[] in bottom-up manner using // recursive formula explained above. for (int i = 0; i <= n; i++) { if (i <= 2) dp[i] = i; else dp[i] = dp[i - 1] + (i - 1) * dp[i - 2]; } return dp[n]; } // Driver code public static void Main() { int n = 4; Console.Write(countFriendsPairings(n)); } } // This code is contributed by nitin mittal.
PHP // PHP program solution for // friends pairing problem // Returns count of ways n people // can remain single or paired up. function countFriendsPairings($n) { $dp[$n + 1] = 0; // Filling dp[] in bottom-up // manner using recursive formula // explained above. for ($i = 0; $i <= $n; $i++) { if ($i <= 2) $dp[$i] = $i; else $dp[$i] = $dp[$i - 1] + ($i - 1) * $dp[$i - 2]; } return $dp[$n]; } // Driver code $n = 4; echo countFriendsPairings($n) ; // This code is contributed // by nitin mittal. ?> JavaScript <script> // Javascript program for solution of // friends pairing problem // Returns count of ways n people // can remain single or paired up. function countFriendsPairings(n) { let dp = []; // Filling dp[] in bottom-up manner using // recursive formula explained above. for (let i = 0; i <= n; i++) { if (i <= 2) dp[i] = i; else dp[i] = dp[i - 1] + (i - 1) * dp[i - 2]; } return dp[n]; } // Driver Code let n = 4; document.write(countFriendsPairings(n)); </script>
Изход
10
Времева сложност: O(n)
Помощно пространство: O(n)
Друг подход: (Използване на рекурсия)
C++// C++ program for solution of friends // pairing problem Using Recursion #include using namespace std; int dp[1000]; // Returns count of ways n people // can remain single or paired up. int countFriendsPairings(int n) { if (dp[n] != -1) return dp[n]; if (n > 2) return dp[n] = countFriendsPairings(n - 1) + (n - 1) * countFriendsPairings(n - 2); else return dp[n] = n; } // Driver code int main() { memset(dp -1 sizeof(dp)); int n = 4; cout << countFriendsPairings(n) << endl; // this code is contributed by Kushdeep Mittal }
Java // Java program for solution of friends // pairing problem Using Recursion import java.io.*; class GFG { static int[] dp = new int[1000]; // Returns count of ways n people // can remain single or paired up. static int countFriendsPairings(int n) { if (dp[n] != -1) return dp[n]; if (n > 2) return dp[n] = countFriendsPairings(n - 1) + (n - 1) * countFriendsPairings(n - 2); else return dp[n] = n; } // Driver code public static void main(String[] args) { for (int i = 0; i < 1000; i++) dp[i] = -1; int n = 4; System.out.println(countFriendsPairings(n)); } } // This code is contributed by Ita_c.
Python3 # Python3 program for solution of friends # pairing problem Using Recursion dp = [-1] * 1000 # Returns count of ways n people # can remain single or paired up. def countFriendsPairings(n): global dp if(dp[n] != -1): return dp[n] if(n > 2): dp[n] = (countFriendsPairings(n - 1) + (n - 1) * countFriendsPairings(n - 2)) return dp[n] else: dp[n] = n return dp[n] # Driver Code n = 4 print(countFriendsPairings(n)) # This code contributed by PrinciRaj1992
C# // C# program for solution of friends // pairing problem Using Recursion using System; class GFG { static int[] dp = new int[1000]; // Returns count of ways n people // can remain single or paired up. static int countFriendsPairings(int n) { if (dp[n] != -1) return dp[n]; if (n > 2) return dp[n] = countFriendsPairings(n - 1) + (n - 1) * countFriendsPairings(n - 2); else return dp[n] = n; } // Driver code static void Main() { for (int i = 0; i < 1000; i++) dp[i] = -1; int n = 4; Console.Write(countFriendsPairings(n)); } } // This code is contributed by DrRoot_
PHP // PHP program for solution of friends // pairing problem Using Recursion // Returns count of ways n people // can remain single or paired up. function countFriendsPairings($n) { $dp = array_fill(0 1000 -1); if($dp[$n] != -1) return $dp[$n]; if($n > 2) { $dp[$n] = countFriendsPairings($n - 1) + ($n - 1) * countFriendsPairings($n - 2); return $dp[$n]; } else { $dp[$n] = $n; return $dp[$n]; } } // Driver Code $n = 4; echo countFriendsPairings($n) // This code is contributed by Ryuga ?> JavaScript <script> // Javascript program for solution of friends // pairing problem Using Recursion let dp = new Array(1000); // Returns count of ways n people // can remain single or paired up. function countFriendsPairings(n) { if (dp[n] != -1) return dp[n]; if (n > 2) return dp[n] = countFriendsPairings(n - 1) + (n - 1) * countFriendsPairings(n - 2); else return dp[n] = n; } // Driver code for (let i = 0; i < 1000; i++) dp[i] = -1; let n = 4; document.write(countFriendsPairings(n)); // This code is contributed by rag2127 </script>
Изход
10
Времева сложност: O(n)
Помощно пространство: O(n)
Тъй като горната формула е подобна на число на фибоначи можем да оптимизираме пространството с итеративно решение.
C++#include using namespace std; // Returns count of ways n people // can remain single or paired up. int countFriendsPairings(int n) { int a = 1 b = 2 c = 0; if (n <= 2) { return n; } for (int i = 3; i <= n; i++) { c = b + (i - 1) * a; a = b; b = c; } return c; } // Driver code int main() { int n = 4; cout << countFriendsPairings(n); return 0; } // This code is contributed by mits
Java import java.io.*; class GFG { // Returns count of ways n people // can remain single or paired up. static int countFriendsPairings(int n) { int a = 1 b = 2 c = 0; if (n <= 2) { return n; } for (int i = 3; i <= n; i++) { c = b + (i - 1) * a; a = b; b = c; } return c; } // Driver code public static void main(String[] args) { int n = 4; System.out.println(countFriendsPairings(n)); } } // This code is contributed by Ravi Kasha.
Python3 # Returns count of ways n people # can remain single or paired up. def countFriendsPairings(n): a b c = 1 2 0; if (n <= 2): return n; for i in range(3 n + 1): c = b + (i - 1) * a; a = b; b = c; return c; # Driver code n = 4; print(countFriendsPairings(n)); # This code contributed by Rajput-Ji
C# using System; class GFG { // Returns count of ways n people // can remain single or paired up. static int countFriendsPairings(int n) { int a = 1 b = 2 c = 0; if (n <= 2) { return n; } for (int i = 3; i <= n; i++) { c = b + (i - 1) * a; a = b; b = c; } return c; } // Driver code public static void Main(String[] args) { int n = 4; Console.WriteLine(countFriendsPairings(n)); } } // This code has been contributed by 29AjayKumar
PHP // Returns count of ways n people // can remain single or paired up. function countFriendsPairings($n) { $a = 1; $b = 2; $c = 0; if ($n <= 2) { return $n; } for ($i = 3; $i <= $n; $i++) { $c = $b + ($i - 1) * $a; $a = $b; $b = $c; } return $c; } // Driver code $n = 4; print(countFriendsPairings($n)); // This code is contributed by mits ?> JavaScript <script> // Returns count of ways n people // can remain single or paired up. function countFriendsPairings(n) { let a = 1 b = 2 c = 0; if (n <= 2) { return n; } for (let i = 3; i <= n; i++) { c = b + (i - 1) * a; a = b; b = c; } return c; } // Driver code let n = 4; document.write(countFriendsPairings(n)); // This code is contributed by avanitrachhadiya2155 </script>
Изход
10
Времева сложност: O(n)
Помощно пространство: О(1)
Друг подход: Тъй като можем да решим горния проблем с помощта на математика, решението по-долу се прави без използване на динамично програмиране.
C++// C++ soln using mathematical approach #include using namespace std; void preComputeFact(vector<long long int>& fact int n) { for(int i = 1; i <= n; i++) fact.push_back(fact[i - 1] * i); } // Returns count of ways n people // can remain single or paired up. int countFriendsPairings(vector<long long int> fact int n) { int ones = n twos = 1 ans = 0; while (ones >= 0) { // pow of 1 will always be one ans += fact[n] / (twos * fact[ones] * fact[(n - ones) / 2]); ones -= 2; twos *= 2; } return ans; } // Driver code int main() { vector<long long int> fact; fact.push_back(1); preComputeFact(fact 100); int n = 4; cout << countFriendsPairings(fact n) << endl; return 0; } // This code is contributed by rajsanghavi9.
Java // Java soln using mathematical approach import java.util.*; class GFG{ static Vector<Integer> fact; static void preComputeFact( int n) { for(int i = 1; i <= n; i++) fact.add(fact.elementAt(i - 1) * i); } // Returns count of ways n people // can remain single or paired up. static int countFriendsPairings(int n) { int ones = n twos = 1 ans = 0; while (ones >= 0) { // pow of 1 will always be one ans += fact.elementAt(n) / (twos * fact.elementAt(ones) * fact.elementAt((n - ones) / 2)); ones -= 2; twos *= 2; } return ans; } // Driver code public static void main(String[] args) { fact = new Vector<>(); fact.add(1); preComputeFact(100); int n = 4; System.out.print(countFriendsPairings(n) +'n'); } } // This code is contributed by umadevi9616
Python3 # Python3 soln using mathematical approach # factorial array is stored dynamically fact = [1] def preComputeFact(n): for i in range(1 n+1): fact.append((fact[i-1]*i)) # Returns count of ways n people # can remain single or paired up. def countFriendsPairings(n): ones = n twos = 1 ans = 0 while(ones >= 0): # pow of 1 will always be one ans = ans + (fact[n]//(twos*fact[ones]*fact[(n-ones)//2])) ones = ones - 2 twos = twos * 2 return(ans) # Driver Code # pre-compute factorial preComputeFact(1000) n = 4 print(countFriendsPairings(n)) # solution contributed by adarsh_007
C# // C# program to implement the approach using System; using System.Collections.Generic; public class GFG { // initializing the fact list static List<int> fact = new List<int>(); // computing the next n values of fact static void preComputeFact(int n) { for (int i = 1; i <= n; i++) { fact.Add(fact[i - 1] * i); } } // Returns count of ways n people // can remain single or paired up. static int countFriendsPairings(int n) { int ones = n; int twos = 1; int ans = 0; while (ones >= 0) { // pow of 1 will always be one ans += fact[n] / (twos * fact[ones] * fact[(n - ones) / 2]); ones -= 2; twos *= 2; } return ans; } // driver code static public void Main() { // initializing the first element of fact fact.Add(1); preComputeFact(100); int n = 4; Console.Write(countFriendsPairings(n)); } } // this code is contributed by phasing17
JavaScript <script> // Javascript soln using mathematical approach // factorial array is stored dynamically let fact = [1]; function preComputeFact(n) { for(let i=1;i<n+1;i++) { fact.push((fact[i-1]*i)); } } // Returns count of ways n people // can remain single or paired up. function countFriendsPairings(n) { let ones = n let twos = 1; let ans = 0; while(ones >= 0) { // pow of 1 will always be one ans = ans + Math.floor(fact[n]/(twos*fact[ones]* fact[(n-ones)/2])) ones = ones - 2 twos = twos * 2 } return ans; } // Driver Code // pre-compute factorial preComputeFact(1000) n = 4 document.write(countFriendsPairings(n)) // This code is contributed by ab2127 </script>
Изход
10
Времева сложност: O(n)
Помощно пространство: O(n)