Top Down DP || Memoization || Accepted Solution || O(n^2) O(n^2)
Approach\n Describe your approach to solving the problem. \nI don\'t really like bottom up DP, so I always try me best to come up with top down approach. It is 
# Approach\n<!-- Describe your approach to solving the problem. -->\nI don\'t really like bottom up DP, so I always try me best to come up with top down approach. It is more natural and easy to explain in the interview. \nYou can also explain the optimal bottom up solution as the follow up later.\nHere is the tip why my code get Accepted:\n1. **@lru_cache(None)**\n2. **if len(nums) - i > time:** only check if there is enough elements left in time\nThese code, I found down in [this solution](https://leetcode.com/problems/minimum-time-to-make-array-sum-at-most-x/solutions/3920367/recursive-solution-o-n-2-beats-nobody)\n# Complexity\n- Time complexity: O(n^2)\n<!-- Add your time complexity here, e.g. $$O(n)$$ -->\n\n- Space complexity: O(n^2)\n<!-- Add your space complexity here, e.g. $$O(n)$$ -->\n\n# Code\n```python3 []\nclass Solution:\n    def minimumTime(self, nums1: List[int], nums2: List[int], x: int) -> int:\n        nums = sorted(list(zip(nums2, nums1)), reverse = True)\n        @lru_cache(None)\n        def dfs(i, time): # return maximum value after "time"\n            if time == 0: return 0\n            if i == len(nums1): return 0\n            # take this number\n            speed, start = nums[i]\n            local_res = start + speed * time + dfs(i+1, time-1)\n            # skip this number, only in the case that there is enough elements left for time\n            if len(nums) - i > time:\n                local_res = max(local_res, dfs(i+1, time))\n            return local_res\n  \n        sum1 = sum(nums1)\n        sum2 = sum(nums2)\n        for time in range(len(nums) + 1):\n            result = sum1 + time * sum2 - dfs(0, time)\n            if result <= x: return time\n        return -1\n```
['Dynamic Programming', 'Memoization', 'Sorting', 'Python3']