Open In App

Maximizing Smallest Flower Height in Garden with Watering Constraint

Last Updated : 23 Dec, 2023
Improve
Improve
Like Article
Like
Save
Share
Report

You have a garden with n flowers lined up in a row. The height of ith flower is ai units. You will water them for k days. In one day you can water w continuous flowers (you can do this only once in a single day). Whenever you water a flower its height increases by 1 unit. You need to maximize the height of the smallest flower all the time.

Examples:

Input: n = 6, k = 2, w = 3, a[] = {2, 2, 2, 2, 1, 1}
Output: 2
Explanation: Water last three flowers for first day & first three flowers for second day.The new heights will be {3, 3, 3, 3, 2, 2}

Input: n = 2, k = 5, w = 1, a[] = {5, 8}
Output: 9
Explanation: For the first four days water the first flower then water the last flower once.

Approach: To solve the problem follow the below idea:

The idea is to use binary search between the minimum and maximum possible height of the tree and at every iteration of the binary search check if we can get the minimum of the tree equal to the mid value of the binary search by watering the trees k times or not.

Step-by-step approach:

  • Initially take the answer as 0 and do a binary search between the minimum and maximum possible height of the tree, i.e: l=0 and h=10^14.
  • Run a loop while(l<=h) for binary searching.
    • Find mid = (l+h)/2
    • Now check if this mid value is one of the possible values for our answer or not, if it is possible to get the minimum of the tree to be equal to mid then update the answer as mid and l=mid+1.
      • To check whether this mid value is valid or not we call another function isValid this function implementation is as follows:
        • Create an array ps which keeps track of which tree is increased by how many heights and initialize it with zero.
        • Now run a loop and check if the initial height+increased height(a[i]+ps[i]) is less than the mid then increase the ith height with the required value so that its height is equal to mid, and along with that we also increase the height the next w trees as we can increase the height of w trees in one time.
        • When coming out of the loop check if k is greater than or equal to we increased the height of the tree then true else return false.
    • Else if this mid value is not a possible value then updates h=mid-1.
  • Return answer.

Below is the implementation of the above approach:

C++




// C++ code for the above approach:
#include <bits/stdc++.h>
using namespace std;
 
// Function to check if current minimum height
// is valid or not.
bool isvalid(std::vector<int>& a, int n, int k, int w,
             long long int mid)
{
    // Array to store the prefix sum of the
    // previous heights.
    long long int ps[n];
    fill(ps, ps + n, 0ll);
    long long int ans = 0;
 
    // Iterating over each height.
    for (long long int i = 0; i < n; i++) {
 
        // Calculating the prefix sum and
        // checking if the current height is less
        // than the current minimum height.
        if (i - 1 >= 0)
            ps[i] += ps[i - 1];
        if (a[i] + ps[i] < mid) {
 
            // Updating the prefix sum and the
            // total number of adjustments
            // required.
            long long int e = mid - a[i] - ps[i];
            ans += e;
            ps[i] += e;
 
            // Reducing the height adjustments
            // for the next window of width w.
            if (i + w < n)
                ps[i + w] -= e;
        }
    }
 
    // Checking if the total adjustments
    // required is less than or equal to k.
    return (ans <= k);
}
 
// Function to maximize the minimum height.
long long int maximizeMinHeight(int n, int k, int w,
                                vector<int>& a)
{
    long long int ans = 0;
    long long int l = 0, h = 1e14;
 
    // Binary search to find the maximum
    // valid minimum height.
    while (l <= h) {
        long long int mid = (l + h) / 2;
 
        // Checking if the current height
        // is valid.
        if (isvalid(a, n, k, w, mid)) {
 
            // Updating the lower bound.
            l = mid + 1;
 
            // Updating the maximum valid minimum
            // height.
            ans = mid;
        }
 
        // Updating the upper bound.
        else {
            h = mid - 1;
        }
    }
 
    // Returning the maximum valid minimum
    // height.
    return ans;
}
 
// Drivers code
int main()
{
    int n = 6, k = 2, w = 3;
    vector<int> a = { 2, 2, 2, 2, 1, 1 };
    long long int result = maximizeMinHeight(n, k, w, a);
 
    // Function Call
    cout << "Maximum valid minimum height: " << result
         << endl;
 
    return 0;
}


Java




import java.util.Arrays;
import java.util.Vector;
 
public class Main {
    // Function to check if current minimum height is valid
    // or not.
    static boolean isValid(Vector<Integer> a, int n, int k,
                           int w, long mid)
    {
        // Array to store the prefix sum of the previous
        // heights.
        long[] ps = new long[n];
        Arrays.fill(ps, 0L);
        long ans = 0;
 
        // Iterating over each height.
        for (int i = 0; i < n; i++) {
            // Calculating the prefix sum and checking if
            // the current height is less than the current
            // minimum height.
            if (i - 1 >= 0)
                ps[i] += ps[i - 1];
            if (a.get(i) + ps[i] < mid) {
                // Updating the prefix sum and the total
                // number of adjustments required.
                long e = mid - a.get(i) - ps[i];
                ans += e;
                ps[i] += e;
 
                // Reducing the height adjustments for the
                // next window of width w.
                if (i + w < n)
                    ps[i + w] -= e;
            }
        }
 
        // Checking if the total adjustments required is
        // less than or equal to k.
        return ans <= k;
    }
 
    // Function to maximize the minimum height.
    static long maximizeMinHeight(int n, int k, int w,
                                  Vector<Integer> a)
    {
        long ans = 0;
        long l = 0, h = (long)1e14;
 
        // Binary search to find the maximum valid minimum
        // height.
        while (l <= h) {
            long mid = (l + h) / 2;
 
            // Checking if the current height is valid.
            if (isValid(a, n, k, w, mid)) {
                // Updating the lower bound.
                l = mid + 1;
 
                // Updating the maximum valid minimum
                // height.
                ans = mid;
            }
            else {
                // Updating the upper bound.
                h = mid - 1;
            }
        }
 
        // Returning the maximum valid minimum height.
        return ans;
    }
 
    // Driver code
    public static void main(String[] args)
    {
        int n = 6, k = 2, w = 3;
        Vector<Integer> a
            = new Vector<>(Arrays.asList(2, 2, 2, 2, 1, 1));
        long result = maximizeMinHeight(n, k, w, a);
 
        // Function Call
        System.out.println("Maximum valid minimum height: "
                           + result);
    }
}


Python3




# Python code for the above approach
from typing import List
 
# Function to check if current minimum height
# is valid or not.
 
 
def is_valid(a: List[int], n: int, k: int, w: int, mid: int) -> bool:
    # Array to store the prefix sum of the
    # previous heights.
    ps = [0] * n
    ans = 0
 
    # Iterating over each height.
    for i in range(n):
        # Calculating the prefix sum and
        # checking if the current height is less
        # than the current minimum height.
        if i - 1 >= 0:
            ps[i] += ps[i - 1]
        if a[i] + ps[i] < mid:
            # Updating the prefix sum and the
            # total number of adjustments
            # required.
            e = mid - a[i] - ps[i]
            ans += e
            ps[i] += e
 
            # Reducing the height adjustments
            # for the next window of width w.
            if i + w < n:
                ps[i + w] -= e
 
    # Checking if the total adjustments
    # required is less than or equal to k.
    return ans <= k
 
# Function to maximize the minimum height.
 
 
def maximize_min_height(n: int, k: int, w: int, a: List[int]) -> int:
    ans = 0
    l, h = 0, 1e14
 
    # Binary search to find the maximum
    # valid minimum height.
    while l <= h:
        mid = (l + h) // 2
 
        # Checking if the current height
        # is valid.
        if is_valid(a, n, k, w, mid):
            # Updating the lower bound.
            l = mid + 1
 
            # Updating the maximum valid minimum
            # height.
            ans = mid
        # Updating the upper bound.
        else:
            h = mid - 1
 
    # Returning the maximum valid minimum
    # height.
    return ans
 
 
# Drivers code
if __name__ == "__main__":
    n, k, w = 6, 2, 3
    a = [2, 2, 2, 2, 1, 1]
    result = maximize_min_height(n, k, w, a)
 
    # Function Call
    print("Maximum valid minimum height:", result)


C#




using System;
using System.Collections.Generic;
 
class Program
{
    // Function to check if current minimum height
    // is valid or not.
    static bool IsValid(List<int> a, int n, int k, int w, long mid)
    {
        // Array to store the prefix sum of the
        // previous heights.
        long[] ps = new long[n];
        Array.Fill(ps, 0L);
        long ans = 0;
 
        // Iterating over each height.
        for (long i = 0; i < n; i++)
        {
            // Calculating the prefix sum and
            // checking if the current height is less
            // than the current minimum height.
            if (i - 1 >= 0)
                ps[i] += ps[i - 1];
            if (a[(int)i] + ps[i] < mid)
            {
                // Updating the prefix sum and the
                // total number of adjustments
                // required.
                long e = mid - a[(int)i] - ps[i];
                ans += e;
                ps[i] += e;
 
                // Reducing the height adjustments
                // for the next window of width w.
                if (i + w < n)
                    ps[i + w] -= e;
            }
        }
 
        // Checking if the total adjustments
        // required is less than or equal to k.
        return ans <= k;
    }
 
    // Function to maximize the minimum height.
    static long MaximizeMinHeight(int n, int k, int w, List<int> a)
    {
        long ans = 0;
        long l = 0, h = (long)1e14;
 
        // Binary search to find the maximum
        // valid minimum height.
        while (l <= h)
        {
            long mid = (l + h) / 2;
 
            // Checking if the current height
            // is valid.
            if (IsValid(a, n, k, w, mid))
            {
                // Updating the lower bound.
                l = mid + 1;
 
                // Updating the maximum valid minimum
                // height.
                ans = mid;
            }
            // Updating the upper bound.
            else
            {
                h = mid - 1;
            }
        }
 
        // Returning the maximum valid minimum
        // height.
        return ans;
    }
 
    // Drivers code
    static void Main()
    {
        int n = 6, k = 2, w = 3;
        List<int> a = new List<int> { 2, 2, 2, 2, 1, 1 };
        long result = MaximizeMinHeight(n, k, w, a);
 
        // Function Call
        Console.WriteLine("Maximum valid minimum height: " + result);
 
        // Keep console window open in debug mode.
        Console.ReadKey();
    }
}


Javascript




// Function to check if current minimum height
// is valid or not.
function isValid(a, n, k, w, mid) {
    // Array to store the prefix sum of the
    // previous heights.
    const ps = new Array(n).fill(0);
    let ans = 0;
 
    // Iterating over each height.
    for (let i = 0; i < n; i++) {
        // Calculating the prefix sum and
        // checking if the current height is less
        // than the current minimum height.
        if (i - 1 >= 0) {
            ps[i] += ps[i - 1];
        }
        if (a[i] + ps[i] < mid) {
            // Updating the prefix sum and the
            // total number of adjustments
            // required.
            const e = mid - a[i] - ps[i];
            ans += e;
            ps[i] += e;
 
            // Reducing the height adjustments
            // for the next window of width w.
            if (i + w < n) {
                ps[i + w] -= e;
            }
        }
    }
 
    // Checking if the total adjustments
    // required is less than or equal to k.
    return ans <= k;
}
 
// Function to maximize the minimum height.
function maximizeMinHeight(n, k, w, a) {
    let ans = 0;
    let l = 0,
        h = 1e14;
 
    // Binary search to find the maximum
    // valid minimum height.
    while (l <= h) {
        const mid = Math.floor((l + h) / 2);
 
        // Checking if the current height
        // is valid.
        if (isValid(a, n, k, w, mid)) {
            // Updating the lower bound.
            l = mid + 1;
 
            // Updating the maximum valid minimum
            // height.
            ans = mid;
        } else {
            // Updating the upper bound.
            h = mid - 1;
        }
    }
 
    // Returning the maximum valid minimum
    // height.
    return ans;
}
 
// Drivers code
function main() {
    const n = 6,
        k = 2,
        w = 3;
    const a = [2, 2, 2, 2, 1, 1];
    const result = maximizeMinHeight(n, k, w, a);
 
    // Function Call
    console.log(`Maximum valid minimum height: ${result}`);
}
 
main();
 
 
// This code is contributed by rambabuguphka


Output

Maximum valid minimum height: 2








Time Complexity: O(NLogN)
Auxiliary Space: O(N)



Like Article
Suggest improvement
Share your thoughts in the comments

Similar Reads