C++ | 4 Approaches |  Recursion -> Memoization -> Tabulation -> Binary Search
1. Recursion\nCODE:\n\n    // Recursion  *** Will Give TLE \n    int solve(int idx, int prev, vector> &arr, int n) {\n        if(idx == n)\n            return 0
**1. Recursion\nCODE:**\n\n    // Recursion  *** Will Give TLE ***\n    int solve(int idx, int prev, vector<vector<int>> &arr, int n) {\n        if(idx == n)\n            return 0;\n        int take = 0, untake = 0;\n        untake = solve(idx+1, prev, arr, n);\n        if((prev == -1) || (arr[idx][0] > arr[prev][0] && arr[idx][1] > arr[prev][1])) {\n            take = 1 + solve(idx+1, idx, arr, n);\n        }\n        return max(take, untake);\n    }\n    int maxEnvelopes(vector<vector<int>>& envelopes) {\n        int n = envelopes.size();\n        sort(envelopes.begin(), envelopes.end());\n        return solve(0, -1, envelopes, n);\n    }\n\t\t\n**2. Recursion + Memoization\nCODE:**\n\n\t// Memoization  *** Will Give TLE ***\n     int solve(int idx, int prev, vector<vector<int>> &arr, int n, vector<vector<int>>&dp) {\n        if(idx == n)\n            return 0;\n        int take = 0, untake = 0;\n        if(dp[idx][prev+1] != -1)\n            return dp[idx][prev+1];\n        untake = solve(idx+1, prev, arr, n, dp);\n        if((prev == -1) || (arr[idx][0] > arr[prev][0] && arr[idx][1] > arr[prev][1])) {\n            take = 1 + solve(idx+1, idx, arr, n, dp);\n        }\n        return dp[idx][prev+1] = max(take, untake);\n    }\n    \n    int maxEnvelopes(vector<vector<int>>& envelopes) {\n        int n = envelopes.size();\n        sort(envelopes.begin(), envelopes.end());\n        vector<vector<int>>dp(n, vector<int>(n+1, -1));\n        return solve(0, -1, envelopes, n, dp);\n    }\n\t\t\n\t\t\n**3. Tabulation\nCODE:**\n \n\t // Tabulation  *** Will Give TLE ***\n\t\tint maxEnvelopes(vector<vector<int>>& envelopes) {\n\t\t\tint n = envelopes.size();\n\t\t\tif(n == 0)\n\t\t\t\treturn 0;\n\t\t\tsort(envelopes.begin(), envelopes.end());\n\t\t\tvector<int>dp(n, 1);\n\t\t\tint take = 0, untake = 0;\n\t\t\tfor(int idx = 0; idx < n; idx++) {\n\t\t\t\tfor(int prev = 0; prev < idx; prev++) {\n\t\t\t\t\tif(envelopes[idx][0] > envelopes[prev][0] && envelopes[idx][1] > envelopes[prev][1]) {\n\t\t\t\t\t\tdp[idx] = max(dp[idx], 1 + dp[prev]);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn *max_element(dp.begin(),dp.end());\n\t\t}\n\t\t\n\t\t\n**4. Binary Search Approach\nCODE:**\n\n\t // Binary Search\n\t\t  static bool comp(const vector<int> &a, const vector<int> &b) {\n\t\t\tif(a[0] < b[0])\n\t\t\t\treturn true;\n\t\t\telse if(a[0] > b[0])\n\t\t\t\treturn false;\n\t\t\telse if(a[1] > b[1])\n\t\t\t\treturn true;\n\t\t\telse\n\t\t\t\treturn false;\n\t\t  } \n\t\t  int maxEnvelopes(vector<vector<int>>& envelopes) {\n\t\t\tsort(envelopes.begin(), envelopes.end(), comp);\n\t\t\tvector<int> dp;\n\t\t\tfor (auto it : envelopes)\n\t\t\t{\n\t\t\t\tauto iter = lower_bound(dp.begin(), dp.end(), it[1]);\n\t\t\t\tif (iter == dp.end())\n\t\t\t\t\tdp.push_back(it[1]);\n\t\t\t\telse if (it[1] < *iter)\n\t\t\t\t\t*iter = it[1];\n\t\t\t}\n\t\t\treturn dp.size();\n\t\t}\n
['Binary Search', 'Dynamic Programming']