Optimising Dynamic Programming Approach for Painter’s Problem using Precomputation

The time complexity of the above program is O(k∗N3). It can be easily brought down to O(k∗N2) by pre-computing the cumulative sums in an array, thus avoiding repeated calls to the sum function.

Below is the how we can achieve this optimisation:

C++




int sum[n + 1] = { 0 };
 
// sum from 1 to i elements of arr
for (int i = 1; i <= n; i++)
    sum[i] = sum[i - 1] + arr[i - 1];
 
for (int i = 1; i <= n; i++)
    dp[1][i] = sum[i];
 
// and using it to calculate the result as:
best = min(best, max(dp[i - 1][p], sum[j] - sum[p]));


Java




int sum[] = new int[n + 1];
 
// sum from 1 to i elements of arr
for (int i = 1; i <= n; i++)
    sum[i] = sum[i - 1] + arr[i - 1];
 
for (int i = 1; i <= n; i++)
    dp[1][i] = sum[i];
 
// and using it to calculate the result as:
best = Math.min(best,
                Math.max(dp[i - 1][p], sum[j] - sum[p]));
 
// This code is contributed by divyesh072019.


Python3




sum = [0] * (n + 1)
 
# sum from 1 to i elements of arr
for i in range(1, n + 1):
    sum[i] = sum[i-1] + arr[i-1]
 
for i in range(1, n + 1):
    dp[1][i] = sum[i]
 
# and using it to calculate the result as:
best = min(best, max(dp[i-1][p], sum[j] - sum[p]))
 
# This code is contributed by kraanzu.


C#




int[] sum = new int[n + 1];
 
// sum from 1 to i elements of arr
for (int i = 1; i <= n; i++)
    sum[i] = sum[i - 1] + arr[i - 1];
 
for (int i = 1; i <= n; i++)
    dp[1, i] = sum[i];
 
// and using it to calculate the result as:
best = Math.Min(best,
                Math.Max(dp[i - 1][p], sum[j] - sum[p]));
 
// This code is contributed by divyeshrabadiya07.


Javascript




<script>
let sum = new Array(n+1);
   
// sum from 1 to i elements of arr
for (let i = 1; i <= n; i++)
  sum[i] = sum[i-1] + arr[i-1];
  
for (let i = 1; i <= n; i++)
  dp[1][i] = sum[i];
  
// and using it to calculate the result as:
best = Math.min(best, Math.max(dp[i-1][p], sum[j] - sum[p]));
 
// This code is contributed by Saurabh Jaiswal.
</script>


Note: Though here we consider dividing A into k or fewer partitions, we can observe that the optimal case always occurs when we divide A into exactly k partitions

So we can use: 

C++




for (int i = k - 1; i <= n; i++)
    best = min(best, max(partition(arr, i, k - 1),
                         sum(arr, i, n - 1)));


Java




for (int i = k - 1; i <= n; i++)
    best = Math.min(best, Math.max(partition(arr, i, k - 1),
                                   sum(arr, i, n - 1)));
 
// This code is contributed by pratham76.


Python3




for i range(k-1, n+1):
    best = min(best, max(partition(arr, i, k-1), sum(arr, i, n-1)))
 
# This code is contributed by Aman Kumar.


C#




for (int i = k - 1; i <= n; i++)
    best = Math.Min(best, Math.Max(partition(arr, i, k - 1),
                                   sum(arr, i, n - 1)));
 
// This code is contributed by rutvik_56


Javascript




for(var i = k - 1; i <= n; i++)
      best = Math.min(best, Math.max(partition(arr, i, k - 1),
                                           sum(arr, i, n - 1)));
                                            
// This code is contributed by Ankita saini


Exercise: 

Can you come up with a solution to this Painter’s Problem using Binary Search



The Painter’s Partition Problem

Given are N boards of with length of each given in the form of array, and K painters, such that each painter takes 1 unit of time to paint 1 unit of the board. The task is to find the minimum time to paint all boards under the constraints that any painter will only paint continuous sections of boards, say board {2, 3, 4} or only board {1} or nothing but not board {2, 4, 5}.

Examples: 

Input: N = 4, A = {10, 10, 10, 10}, K = 2 

Output : 20

Explanation: Here we can divide the boards into 2 equal sized partitions (Painter 1 will paint boards A1 and A2, and Painter 2 will paint boards A3 and A4). So each painter gets 20 units of board and the total time taken is 20. 

Input: N = 4, A = {10, 20, 30, 40}, K = 2 

Output : 60

Explanation: Since there are only 2 painters, therefore divide first 3 boards to painter 1 (A1, A2 and A3) with time = 60, and last board to painter 2 (A4) with time = 40. Therefore total time taken = 60, which is the minimum possible.

Please note the combination A1 and A4 to Painter 1 with time 50, and A2 and A3 to Painter 2 with time 50, will yield a smaller time (50 units). But this cant be considered due to the constraint that a painter cannot paint non-continuos series of boards.

Similar Reads

Naive Approach for Painter’s Problem:

A brute force solution is to consider all possible sets of contiguous partitions and calculate the maximum sum partition in each case and return the minimum of all these cases....

Dynamic Programming Approach for Painter’s Problem

The above approach can be further optimised using Dynamic Programming approach....

Optimising Dynamic Programming Approach for Painter’s Problem using Precomputation

...