My C++ code (DP, O(N^3)) 20ms
The algorithm is well explained in [1] and I pretty much followed the same line.\n1) First version I got is recursion +backtracing (TLE)\n2) Second version I go
The algorithm is well explained in [1] and I pretty much followed the same line.\n1) First version I got is recursion +backtracing (TLE)\n2) Second version I got is DP:\ninstead of bursting ballons one by one, we do it in a reverse order, "de-burst" ballons one by one. In that order, the left and right neighbor of the "de-burst" ballon is known. However, the complexity is still high (~ order of C(n,n/2))\n\nThe real challenge is the outer boundaries (i.e. left, right neighbors vary with the burst order). The algorithm in [1] elegantly fixed that problem: fix left/right neighbors and doing DP from length=3 to nSize;\n\n  [1]: https://leetcode.com/discuss/72216/share-some-analysis-and-explanations\n\n    class Solution {\n    public:\n        int maxCoins(vector<int>& nums) {\n            int nSize = nums.size()+2, left, right, len, mid, temp, dpMax[nSize][nSize] ={};\n            nums.insert(nums.begin(),1); // two dummy "1" added to simplify DP\n            nums.push_back(1);\n            \n            for(len=3; len<=nSize; ++len) // lenght including left and right boudaries, \n                for(left=0; left<=nSize-len; ++left)  //left boudary/neighbor\n                    for(right = left+len-1, mid=left+1, temp = nums[left]*nums[right]; mid<right;++mid) //right boundary, mid is the last one to burst in the range (left, right)\n                        dpMax[left][right] = max(dpMax[left][right], dpMax[left][mid] + dpMax[mid][right] + nums[mid]*temp);\n    \n            nums.erase(nums.begin()); // recover nums\n            nums.pop_back();\n            return dpMax[0][nSize-1];        \n        }\n    };
[]