Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <bits/stdc++.h>
- using namespace std;
- int pairFriends(int level, int &n, vector<bool> &visited, unordered_map<string, int> &memo){
- if(level > n){
- return 1;
- }
- string friendsBlocked = "";
- for(int i = 1; i < visited.size(); i++){
- if(visited[i]){
- friendsBlocked += to_string(i);
- }
- }
- string memoKey = to_string(level) + "|" + friendsBlocked;
- if(memo.count(memoKey) > 0){
- return memo[memoKey];
- }
- int single = 0, paired = 0, occupied = 0;
- // YOU can only take decisions if you are not already paired by some other friend.
- // such as we processed 1 and 2 and at level of 3.... if we are on some path where {1, 3},{2} which means 1 at their own level decided to pair up with 3, which will block up 3 and in that path 3 will be marked visited before we even reach 3. So we just move to the next level.
- if(!visited[level]){
- //either go alone/don't pair
- visited[level] = true;
- single = pairFriends(level + 1, n, visited, memo);
- visited[level] = false;
- //form pairs with every friend that is AVAILABLE and not already paired up, and to make this decision too, you also need to be free,i.e. that you should NOT ALSO BELONG to some pair
- //start the loop from level + 1 and not 1 just to avoid permutation... {1, 2} making this pair at level 1, but making this pair {2, 1} at level 2.
- visited[level] = true;
- for(int i = level + 1; i <= n; i++){
- if(!visited[i]){
- visited[i] = true;
- paired += pairFriends(level + 1, n, visited, memo);
- visited[i] = false;
- }
- }
- visited[level] = false;
- }
- else{
- occupied = pairFriends(level + 1, n, visited, memo);
- }
- return memo[memoKey] = single + paired + occupied;
- // return memo[level][] = single + paired + occupied;
- }
- int pairFriendsOptimised(int n, vector<int> &memo){
- if(n == -1){
- return 0;
- }
- if(n == 0){
- return 1;
- }
- //memo check
- if(memo[n] != -1){
- return memo[n];
- }
- int single = 0, paired = 0;
- //go single
- single = pairFriendsOptimised(n - 1, memo);
- //go pair
- // for(int i = 0; i < n - 1; i++){
- // paired += pairFriendsOptimised(n - 2, memo);
- // }
- paired += pairFriendsOptimised(n - 2, memo);
- paired *= (n - 1);
- //IMPORTANT
- //It can be further replaced with simple multiplication though..
- //As the loop runs from (0 -> n - 2)...a total (n - 1) times, which immitates the pairing of for a single person,..if there are total n persons... 1 single person can form (n - 1)pairs
- //ALWAYS BE ON THE LOOKOUT FOR SUCH PATTERNS in counting questions, WHERE FOR LOOP IS JUST MAKING THE SAME CALLS FOR A SET NUMBER OF TIMES, as it is the same call without any change, it will always return a same value. Just call it once and multiply the number of times it was called.
- return memo[n] = single + paired;
- }
- int main() {
- // your code goes here
- int n;
- cin >> n;
- /*
- MEMO Call
- vector<bool> visited(n + 1, false);
- unordered_map<string, int> memo;
- cout << pairFriends(1, n, visited, memo) << '\n';
- */
- /*
- MEMO CALL (Self Thought) Could be optimised when solved the OG MEMO CODE.
- */
- vector<int> memo(n + 1, -1);
- cout << pairFriendsOptimised(n, memo) << '\n';
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement