📌  相关文章
📜  最大化第 K 个索引处的值以创建 N 大小的数组,其相邻差为 1 且总和小于 M

📅  最后修改于: 2021-10-26 07:00:40             🧑  作者: Mango

由于三个数N,KM,任务是找到,如果正值被分配到所有N可以分配到第k个指标的最大价值指数,使得值的总和小于M,且差异相邻位置的值之间最多为 1。

例子:

方法:以下观察有助于解决问题:

  1. 如果在第K 个索引处分配X ,则最优分布如下:
    1. 如果X小于K-1 ,则左侧的最佳分布将是(X-1), (X-2), …(X-K+1), (1), (1)…
    2. 否则,它将是(X-1), (X-2), …(X-K+1)
    3. 如果X小于NK ,则左侧的最佳分布将是(X-1), (X-2), …(X-N+K), 1, 1…
    4. 否则,它将是(X-1), (X-2), …(X-N+K)
  2. 使用AP系列, (X-1)+(X-2)+(X-3)+…+(XY)之和Y*(X-1+XY)/2 = Y*(2X-Y) -1)/2

X的最大值可以用二分查找的概念来计算。请按照以下步骤解决问题:

  1. 将变量ans初始化为-1 ,以存储答案。
  2. 将两个变量low初始化为0并将high初始化为M ,以进行二分查找。
  3. 不大于高时循环并执行以下操作:
    1. 计算mid作为highlow的平均值。
    2. 将变量val初始化为0 ,以存储当前的分布总和。
    3. LK左侧的索引数)初始化为K-1 ,将RK右侧的索引数)初始化为NK
    4. mid的值添加到val
    5. 如上所述在K的左侧和右侧分布数字,并将它们的值添加到val
    6. 如果 val 小于M ,则将 ans 更新为ansmid的最大值。将更新为mid+1
    7. 否则,将更新为mid-1
  4. 返回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)