Maximize value at Kth index to create N size array with adjacent difference 1 and sum less than M
Last Updated :
30 Jun, 2021
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:
- 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++
#include <bits/stdc++.h>
using namespace std;
int calculateMax( int N, int M, int K)
{
int ans = -1;
int low = 0, high = M;
while (low <= high) {
int mid = (low + high) / 2;
int val = 0;
int L = K - 1;
int R = N - K;
val += mid;
if (mid >= L) {
val += (L) * (2 * mid - L - 1) / 2;
}
else {
val += mid * (mid - 1) / 2 + (L - mid);
}
if (mid >= R) {
val += (R) * (2 * mid - R - 1) / 2;
}
else {
val += mid * (mid - 1) / 2 + (R - mid);
}
if (val <= M) {
ans = max(ans, mid);
low = mid + 1;
}
else
high = mid - 1;
}
return ans;
}
int main()
{
int N = 7, M = 100, K = 6;
cout << calculateMax(N, M, K) << endl;
return 0;
}
|
Java
import java.io.*;
class GFG
{
public static int calculateMax( int N, int M, int K)
{
int ans = - 1 ;
int low = 0 , high = M;
while (low <= high)
{
int mid = (low + high) / 2 ;
int val = 0 ;
int L = K - 1 ;
int R = N - K;
val += mid;
if (mid >= L)
{
val += (L) * ( 2 * mid - L - 1 ) / 2 ;
}
else
{
val += mid * (mid - 1 ) / 2 + (L - mid);
}
if (mid >= R)
{
val += (R) * ( 2 * mid - R - 1 ) / 2 ;
}
else
{
val += mid * (mid - 1 ) / 2 + (R - mid);
}
if (val <= M) {
ans = Math.max(ans, mid);
low = mid + 1 ;
}
else
high = mid - 1 ;
}
return ans;
}
public static void main(String[] args)
{
int N = 7 , M = 100 , K = 6 ;
System.out.println(calculateMax(N, M, K));
}
}
|
Python3
def calculateMax(N, M, K):
ans = - 1
low = 0
high = M
while (low < = high):
mid = (low + high) / 2
val = 0
L = K - 1
R = N - K
val + = mid
if (mid > = L):
val + = (L) * ( 2 * mid - L - 1 ) / 2
else :
val + = mid * (mid - 1 ) / 2 + (L - mid)
if (mid > = R):
val + = (R) * ( 2 * mid - R - 1 ) / 2
else :
val + = mid * (mid - 1 ) / 2 + (R - mid)
if (val < = M):
ans = max (ans, mid)
low = mid + 1
else :
high = mid - 1
return int (ans)
N = 7
M = 100
K = 6
print (calculateMax(N, M, K));
|
C#
using System;
class GFG
{
public static int calculateMax( int N, int M, int K)
{
int ans = -1;
int low = 0, high = M;
while (low <= high)
{
int mid = (low + high) / 2;
int val = 0;
int L = K - 1;
int R = N - K;
val += mid;
if (mid >= L)
{
val += (L) * (2 * mid - L - 1) / 2;
}
else
{
val += mid * (mid - 1) / 2 + (L - mid);
}
if (mid >= R)
{
val += (R) * (2 * mid - R - 1) / 2;
}
else
{
val += mid * (mid - 1) / 2 + (R - mid);
}
if (val <= M) {
ans = Math.Max(ans, mid);
low = mid + 1;
}
else
high = mid - 1;
}
return ans;
}
static void Main()
{
int N = 7, M = 100, K = 6;
Console.Write(calculateMax(N, M, K));
}
}
|
Javascript
<script>
function calculateMax(N, M, K)
{
var ans = -1;
var low = 0, high = M;
while (low <= high)
{
var mid = parseInt((low + high) / 2);
var val = 0;
var L = K - 1;
var R = N - K;
val += mid;
if (mid >= L)
{
val += (L) * ((2 * mid - L - 1) / 2);
}
else
{
val += mid * parseInt((mid - 1) / 2) + (L - mid);
}
if (mid >= R)
{
val += (R) * (2 * mid - R - 1) / 2;
}
else
{
val += mid * parseInt((mid - 1) / 2) + (R - mid);
}
if (val <= M)
{
ans = Math.max(ans, mid);
low = mid + 1;
}
else
high = mid - 1;
}
return ans;
}
let N = 7, M = 100, K = 6;
document.write(calculateMax(N, M, K));
</script>
|
Time Complexity: O(LogM)
Auxiliary Space: O(1)
Like Article
Suggest improvement
Share your thoughts in the comments
Please Login to comment...