Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- The idea is that you have to express optimal solution to
- current problem through optimal solutions to (overlapping) subproblems.
- I think, it's better to start with a simple
- example for nums=[1, 2, 3, 4, 5] and m=3.
- The optimal solution for this problem is
- minimum among solutions that include all possible nums prefixes, starting with index 0.
- best([1, 2, 3, 4, 5], 3) is a min(
- max(1, best([2, 3, 4, 5], 2),
- max(1 + 2, best([3, 4, 5], 2),
- max(1 + 2 + 3, best([4, 5], 2),
- )
- We see the recursive structure clearly here. Expressed more formally:
- best(nums, m) is a min(
- max(sum(nums[:i]), best(nums[i:], m-1))
- for i in range(len(len(nums)-m))
- )
- I leave it to you to understand,
- where subproblems overlap here (multiple calls made with same arguments).
- Back to complexity.
- If we remove caching (memoization) implemented through use of visited,
- then we get exponential complexity O(N^N).
- With memoization complexity analysis becomes tricky.
- But we can get a hint from our cache (visited) dimensions,
- that may have at most len(nums) * m unique entries.
- This value corresponds to a number of unique subproblems
- that have to be solved to get final answer.
- Thereby I would say the complexity is O(len(nums) * m) ( O(N * m))
- long long fun (vector<int>& nums, int idx , int m, vector < vector <int> > &dp)
- {
- if (dp[idx][m] != -1)
- {
- return dp[idx][m];
- }
- long long sum = 0;
- long long res = INT_MAX;
- if (m == 0)
- {
- for (int i = idx ; i < nums.size(); i++)
- {
- sum += nums[i];
- }
- return sum;
- }
- for (int i = idx ; i < nums.size(); i ++)
- {
- sum += nums[i];
- res = min (res, max (sum , fun (nums, i + 1, m - 1, dp)));
- }
- dp[idx][m] = res;
- return res ;
- }
- int splitArray(vector<int>& nums, int m) {
- vector <vector <int> > dp (1000 + 2, vector <int> (52, -1) );
- return fun (nums, 0 , m-1 , dp);
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement