由于三个数N,K和M,任务是找到,如果正值被分配到所有N可以分配到第k个指标的最大价值指数,使得值的总和小于M,且差异相邻位置的值之间最多为 1。
例子:
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
方法:以下观察有助于解决问题:
- 如果在第K 个索引处分配X ,则最优分布如下:
- 如果X小于K-1 ,则左侧的最佳分布将是(X-1), (X-2), …(X-K+1), (1), (1)…
- 否则,它将是(X-1), (X-2), …(X-K+1) 。
- 如果X小于NK ,则左侧的最佳分布将是(X-1), (X-2), …(X-N+K), 1, 1…
- 否则,它将是(X-1), (X-2), …(X-N+K) 。
- 使用AP系列, (X-1)+(X-2)+(X-3)+…+(XY)之和为Y*(X-1+XY)/2 = Y*(2X-Y) -1)/2
X的最大值可以用二分查找的概念来计算。请按照以下步骤解决问题:
- 将变量ans初始化为-1 ,以存储答案。
- 将两个变量low初始化为0并将high初始化为M ,以进行二分查找。
- 当低不大于高时循环并执行以下操作:
- 计算mid作为high和low的平均值。
- 将变量val初始化为0 ,以存储当前的分布总和。
- 将L ( K左侧的索引数)初始化为K-1 ,将R ( K右侧的索引数)初始化为NK 。
- 将mid的值添加到val 。
- 如上所述在K的左侧和右侧分布数字,并将它们的值添加到val 。
- 如果 val 小于M ,则将 ans 更新为ans和mid的最大值。将低更新为mid+1 。
- 否则,将高更新为mid-1 。
- 返回ans 。
下面是上述方法的实现:
C++
// C++ program for the above approach
#include
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
输出
16
时间复杂度: O(LogM)
辅助空间: O(1)