Naive Explanation || Backtracking with Memoization 🎀
Approach:\n- We are allowed to either delete first 2 elements or last 2 elemets or first & last elements\n- We will explore all posibilities in all 3 cases.\n- 
# Approach:\n- We are allowed to either delete `first 2 elements` or `last 2 elemets` or `first & last elements`\n- We will explore all posibilities in all `3 cases`.\n- We would use 2 pointers `start` & `end` to keep track of the array, rather than actually deleting the elements of array and creating new one for every recursive call, we will just update our pointers.\n- To optimize our solution we will store the maximum operations possible `maxOps` for the 2 pointers in a `dp` matrix.\n- If we again see the `same pointers` we would just return the pre-calculated `maxOps` result.\n<!-- Describe your approach to solving the problem. -->\n\n# Complexity\n- Time complexity: O(N^2)\n<!-- Add your time complexity here, e.g. $$O(n)$$ -->\n\n- Space complexity: O(N)\n<!-- Add your space complexity here, e.g. $$O(n)$$ -->\n\n# Code\n```cpp []\nclass Solution {\npublic:\n\n    int N;\n    vector<int> nums;\n    vector<vector<int>> dp; // [start, end] = maxOps;\n\n    int backtrack(int start, int end, int prevScore){\n        if(start >= end) return 0;\n        if(dp[start][end] != -1) return dp[start][end];\n\n        int case1 = 0, case2 = 0, case3 = 0;\n\n        if(nums[start] + nums[end] == prevScore)       case1 = backtrack(start + 1, end - 1, prevScore) + 1;\n        if(nums[start] + nums[start + 1] == prevScore) case2 = backtrack(start + 2, end, prevScore) + 1;\n        if(nums[end] + nums[end - 1] == prevScore)     case3 = backtrack(start, end - 2, prevScore) + 1;\n\n        return dp[start][end] = max({case1, case2, case3});\n    }\n\n    int maxOperations(vector<int>& n) {\n        nums = n;\n        N = nums.size();\n        dp = vector<vector<int>>(N, vector<int>(N, -1));\n\n        int first2EleCase = nums[0] + nums[1];               \n        int first2EleCaseOps = backtrack(2, N - 1, first2EleCase);\n\n        int last2EleCase = nums[N - 1] + nums[N - 2];        \n        int last2EleCaseOps = backtrack(0, N - 3, last2EleCase);\n\n        int firstLastEleCase = nums[0] + nums[N - 1];           \n        int firstLastEleCaseOps = backtrack(1, N - 2, firstLastEleCase);\n\n        return max({first2EleCaseOps, last2EleCaseOps, firstLastEleCaseOps}) + 1;\n    }\n};\n```
['Dynamic Programming', 'Backtracking', 'Memoization', 'C++']