Maximize value at Kth index to create N size array with adjacent difference 1 and sum less than M
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)
Last Updated :
30 Jun, 2021
Like Article
Save Article
Share your thoughts in the comments
Please Login to comment...