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>1Input: N=7, M=100, K=6
Output: 16
Approach : The following observations help in solving the problem:
- If X is assigned at the Kth index, then, the optimal distribution is as follows:
- If X is less than K-1, the optimal distribution on than left would be (X-1), (X-2), …(X-K+1), (1), (1)…
- Otherwise, it would be (X-1), (X-2), …(X-K+1).
- If X is less than N-K, the optimal distribution on than left would be (X-1), (X-2), …(X-N+K), 1, 1…
- Otherwise, it would be (X-1), (X-2), …(X-N+K).
- 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:
- Initialize a variable ans to -1, to store the answer.
- Initialize two variables low to 0 and high to M, for the purpose of binary searching.
-
Loop while low is not greater than high and do the following:
- Calculate mid as the mean of high and low.
- Initialize a variable val to 0, to store current sum of distribution.
- 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.
- Add the value of mid to val.
- Distribute numbers on the left and right of K as discussed above and add their values to val.
- If val is less than M, update ans as the maximum of ans and mid. Update low as mid+1.
- Otherwise, update high as mid-1.
- Return ans.
Below is the implementation of the above approach:
// 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 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 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# 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. |
<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>
|
16
Time Complexity: O(LogM)
Auxiliary Space: O(1)