Open In App

Maximize value at Kth index to create N size array with adjacent difference 1 and sum less than M

Improve
Improve
Like Article
Like
Save
Share
Report

Given three numbers N, K, and M, the task is to find the maximum value that can be assigned to the Kth index if positive values are assigned to all N indices such that the total sum of values is less than M, and the difference between the values at adjacent positions is atmost 1.

Examples:

Input : N=3, M=10, K=2
Output: 4
Explanation: The optimal way to assign values is {3, 4, 3}. Total sum=3+4+3=10≤M. 
Note: {3, 4, 2} is not a valid distribution as 4-2=2>1

Input: N=7, M=100, K=6 
Output: 16

Approach : The following observations help in solving the problem:

  1. If X is assigned at the Kth index, then, the optimal distribution is as follows:
    1. If X is less than K-1, the optimal distribution on than left would be (X-1), (X-2), …(X-K+1), (1), (1)…
    2. Otherwise, it would be (X-1), (X-2), …(X-K+1).
    3. If X is less than N-K, the optimal distribution on than left would be (X-1), (X-2), …(X-N+K), 1, 1…
    4. Otherwise, it would be (X-1), (X-2), …(X-N+K).
  2. Using the AP series, the sum of (X-1)+(X-2)+(X-3)+…+(X-Y) is Y*(X-1+X-Y)/2 = Y*(2X-Y-1)/2

The maximum value of X can be calculated with the concept of Binary search. Follow the steps below to solve the problem:

  1. Initialize a variable ans to -1, to store the answer.
  2. Initialize two variables low to 0 and high to M, for the purpose of binary searching.
  3. Loop while low is not greater than high and do the following:
    1. Calculate mid as the mean of high and low.
    2. Initialize a variable val to 0, to store current sum of distribution.
    3. Initialize L(number of indices on the left of K) as K-1 and R(number of indices on the right of K) as N-K.
    4. Add the value of mid to val.
    5. Distribute numbers on the left and right of K as discussed above and add their values to val.
    6. If val is less than M, update ans as the maximum of ans and mid. Update low as mid+1.
    7. Otherwise, update high as mid-1.
  4. Return ans.

Below is the implementation of the above approach:

C++




// C++ program for the above approach
#include <bits/stdc++.h>
using namespace std;
// Function to calculate maximum value that can be placed at
// the Kth index in a distribution in which difference of
// adjacent elements is less than 1 and total sum of
// distribution is M.
int calculateMax(int N, int M, int K)
{
    // variable to store final answer
    int ans = -1;
    // variables for binary search
    int low = 0, high = M;
    // Binary search
    while (low <= high) {
        // variable for binary search
        int mid = (low + high) / 2;
        // variable to store total sum of array
        int val = 0;
        // number of indices on the left excluding the Kth
        // index
        int L = K - 1;
        // number of indices on the left excluding the Kth
        // index
        int R = N - K;
        // add mid to final sum
        val += mid;
        // distribution on left side is possible
        if (mid >= L) {
            // sum of distribution on the left side
            val += (L) * (2 * mid - L - 1) / 2;
        }
        else {
            // sum of distribution on the left side with
            // (L-mid) 1s
            val += mid * (mid - 1) / 2 + (L - mid);
        }
        // distribution on right side is possible
        if (mid >= R) {
            // sum of distribution on the right side
            val += (R) * (2 * mid - R - 1) / 2;
        }
        else {
            // sum of distribution on the left side with
            // (R-mid) 1s
            val += mid * (mid - 1) / 2 + (R - mid);
        }
        // Distribution is valid
        if (val <= M) {
            ans = max(ans, mid);
            low = mid + 1;
        }
        else
            high = mid - 1;
    }
    // return answer
    return ans;
}
// Driver code
int main()
{
    // Input
    int N = 7, M = 100, K = 6;
 
    // Function call
    cout << calculateMax(N, M, K) << endl;
    return 0;
}


Java




// Java program for the above approach
import java.io.*;
 
class GFG
{
 
  // Function to calculate maximum value that can be
  // placed at
  // the Kth index in a distribution in which difference
  // of adjacent elements is less than 1 and total sum of
  // distribution is M.
  public static int calculateMax(int N, int M, int K)
  {
 
    // variable to store final answer
    int ans = -1;
 
    // variables for binary search
    int low = 0, high = M;
 
    // Binary search
    while (low <= high)
    {
 
      // variable for binary search
      int mid = (low + high) / 2;
 
      // variable to store total sum of array
      int val = 0;
 
      // number of indices on the left excluding the
      // Kth index
      int L = K - 1;
 
      // number of indices on the left excluding the
      // Kth index
      int R = N - K;
 
      // add mid to final sum
      val += mid;
 
      // distribution on left side is possible
      if (mid >= L)
      {
 
        // sum of distribution on the left side
        val += (L) * (2 * mid - L - 1) / 2;
      }
      else
      {
 
        // sum of distribution on the left side with
        // (L-mid) 1s
        val += mid * (mid - 1) / 2 + (L - mid);
      }
 
      // distribution on right side is possible
      if (mid >= R)
      {
 
        // sum of distribution on the right side
        val += (R) * (2 * mid - R - 1) / 2;
      }
      else
      {
 
        // sum of distribution on the left side with
        // (R-mid) 1s
        val += mid * (mid - 1) / 2 + (R - mid);
      }
 
      // Distribution is valid
      if (val <= M) {
        ans = Math.max(ans, mid);
        low = mid + 1;
      }
      else
        high = mid - 1;
    }
 
    // return answer
    return ans;
  }
 
  // Driver code
  public static void main(String[] args)
  {
    // Input
    int N = 7, M = 100, K = 6;
 
    // Function call
    System.out.println(calculateMax(N, M, K));
  }
}
 
// This code is contributed by lokeshpotta20.


Python3




# Python3 program for the above approach
 
# Function to calculate maximum value
# that can be placed at the Kth index
# in a distribution in which difference
# of adjacent elements is less than 1
# and total sum of distribution is M.
def calculateMax(N, M, K):
     
    # Variable to store final answer
    ans = -1
     
    # Variables for binary search
    low = 0
    high = M
     
    # Binary search
    while (low <= high):
         
        # Variable for binary search
        mid = (low + high) / 2
         
        # Variable to store total sum of array
        val = 0
         
        # Number of indices on the left excluding
        # the Kth index
        L = K - 1
         
        # Number of indices on the left excluding
        # the Kth index
        R = N - K
         
        # Add mid to final sum
        val += mid
         
        # Distribution on left side is possible
        if (mid >= L):
             
            # Sum of distribution on the left side
            val += (L) * (2 * mid - L - 1) / 2
         
        else:
             
            # Sum of distribution on the left side
            # with (L-mid) 1s
            val += mid * (mid - 1) / 2 + (L - mid)
         
        # Distribution on right side is possible
        if (mid >= R):
             
            # Sum of distribution on the right side
            val += (R) * (2 * mid - R - 1) / 2
         
        else:
             
            # Sum of distribution on the left side with
            # (R-mid) 1s
            val += mid * (mid - 1) / 2 + (R - mid)
         
        # Distribution is valid
        if (val <= M):
            ans = max(ans, mid)
            low = mid + 1
        else:
            high = mid - 1
     
    # Return answer
    return int(ans)
 
# Driver code
 
# Input
N = 7
M = 100
K = 6
 
# Function call
print(calculateMax(N, M, K));
 
# This code is contributed by sanjoy_62


C#




// C# program for the above approach
using System;
class GFG
{
 
  // Function to calculate maximum value that can be
  // placed at
  // the Kth index in a distribution in which difference
  // of adjacent elements is less than 1 and total sum of
  // distribution is M.
  public static int calculateMax(int N, int M, int K)
  {
 
    // variable to store final answer
    int ans = -1;
 
    // variables for binary search
    int low = 0, high = M;
 
    // Binary search
    while (low <= high)
    {
 
      // variable for binary search
      int mid = (low + high) / 2;
 
      // variable to store total sum of array
      int val = 0;
 
      // number of indices on the left excluding the
      // Kth index
      int L = K - 1;
 
      // number of indices on the left excluding the
      // Kth index
      int R = N - K;
 
      // add mid to final sum
      val += mid;
 
      // distribution on left side is possible
      if (mid >= L)
      {
 
        // sum of distribution on the left side
        val += (L) * (2 * mid - L - 1) / 2;
      }
      else
      {
 
        // sum of distribution on the left side with
        // (L-mid) 1s
        val += mid * (mid - 1) / 2 + (L - mid);
      }
 
      // distribution on right side is possible
      if (mid >= R)
      {
 
        // sum of distribution on the right side
        val += (R) * (2 * mid - R - 1) / 2;
      }
      else
      {
 
        // sum of distribution on the left side with
        // (R-mid) 1s
        val += mid * (mid - 1) / 2 + (R - mid);
      }
 
      // Distribution is valid
      if (val <= M) {
        ans = Math.Max(ans, mid);
        low = mid + 1;
      }
      else
        high = mid - 1;
    }
 
    // return answer
    return ans;
  }
 
 
// Driver code
static void Main()
{
   
    // Input
    int N = 7, M = 100, K = 6;
 
    // Function call
    Console.Write(calculateMax(N, M, K));
 
}
}
 
// This code is contributed by code_hunt.


Javascript




<script>
        // JavaScript program for the above approach
 
        // Function to calculate maximum value that can be placed at
        // the Kth index in a distribution in which difference of
        // adjacent elements is less than 1 and total sum of
        // distribution is M.
        function calculateMax(N, M, K)
        {
         
            // variable to store final answer
            var ans = -1;
             
            // variables for binary search
            var low = 0, high = M;
             
            // Binary search
            while (low <= high)
            {
             
                // variable for binary search
                var mid = parseInt((low + high) / 2);
                 
                // variable to store total sum of array
                var val = 0;
                 
                // number of indices on the left excluding the Kth
                // index
                var L = K - 1;
                 
                // number of indices on the left excluding the Kth
                // index
                var R = N - K;
                 
                // add mid to final sum
                val += mid;
                 
                // distribution on left side is possible
                if (mid >= L)
                {
                 
                    // sum of distribution on the left side
                    val += (L) * ((2 * mid - L - 1) / 2);
                }
                else
                {
                 
                    // sum of distribution on the left side with
                    // (L-mid) 1s
                    val += mid * parseInt((mid - 1) / 2) + (L - mid);
                }
                 
                // distribution on right side is possible
                if (mid >= R)
                {
                 
                    // sum of distribution on the right side
                    val += (R) * (2 * mid - R - 1) / 2;
                }
                else
                {
                 
                    // sum of distribution on the left side with
                    // (R-mid) 1s
                    val += mid * parseInt((mid - 1) / 2) + (R - mid);
                }
                 
                // Distribution is valid
                if (val <= M)
                {
                    ans = Math.max(ans, mid);
                    low = mid + 1;
                }
                else
                    high = mid - 1;
            }
             
            // return answer
            return ans;
        }
         
        // Driver code
 
        // Input
        let N = 7, M = 100, K = 6;
 
        // Function call
        document.write(calculateMax(N, M, K));
 
// This code is contributed by lokeshpotta20.
    </script>


Output

16

Time Complexity: O(LogM)
Auxiliary Space: O(1)

 



Last Updated : 30 Jun, 2021
Like Article
Save Article
Previous
Next
Share your thoughts in the comments
Similar Reads