📜  须藤铺位|实习介绍

📅  最后修改于: 2021-05-05 01:44:44             🧑  作者: Mango

给定一个由N个正整数组成的数组A和一个预算B。您的任务是确定要从数组中选取的元素的最大数量,以使所有选取的元素的累积成本小于或等于预算B。第i个元素由下式给出:A [i] +(i * K)其中,K是一个常数,其值等于选取的元素数。索引(i)是基于1的。打印最大数量及其各自的累计成本。

例子:

先决条件:二进制搜索

方法:这里的想法是对K的所有可能值(即要选择的元素的最佳数量)使用二进制搜索。以零开始作为下限,以元素总数结束,即以N作为上限。通过将K设置为当前Mid来检查所获得的累计成本是否小于或等于预算。如果满足条件,则尝试通过将Start设置为(Mid + 1)来增加K,否则尝试通过将End设置为(Mid – 1)来减少K。
通过简单地根据给定的公式修改数组并添加最小的修改值K(当前要拾取的元素的数量)来获得累积成本,可以通过蛮力方式进行条件检查。

下面是上述方法的实现。

C++
// CPP Program to find the optimal number of
// elements such that the cumulative value
// should be less than given number
#include 
  
using namespace std;
  
// This function returns true if the value cumulative
// according to received integer K is less than budget
// B, otherwise returns false
bool canBeOptimalValue(int K, int arr[], int N, int B,
                       int& value)
{
    // Initialize a temporary array which stores
    // the cumulative value of the original array
    int tmp[N];
  
    for (int i = 0; i < N; i++)
        tmp[i] = (arr[i] + K * (i + 1));
  
    // Sort the array to find the smallest K values
    sort(tmp, tmp + N);
  
    value = 0;
    for (int i = 0; i < K; i++)
        value += tmp[i];
  
    // Check if the value is less than budget
    return value <= B;
}
  
// This function prints the optimal number of elements
// and respective cumulative value which is less than
// the given number
void findNoOfElementsandValue(int arr[], int N, int B)
{
    int start = 0; // Min Value or lower bound
  
    int end = N; // Max Value or upper bound
  
    // Initialize answer as zero as optimal value
    // may not exists
    int ans = 0;
  
    int cumulativeValue = 0;
  
    while (start <= end) {
        int mid = (start + end) / 2;
  
        // If the current Mid Value is an optimal
        // value, then try to maximize it
        if (canBeOptimalValue(mid, arr, N, B,
                              cumulativeValue)) {
            ans = mid;
            start = mid + 1;
        }
        else
            end = mid - 1;
    }
    // Call Again to set the corresponding cumulative
    // value for the optimal ans
    canBeOptimalValue(ans, arr, N, B, cumulativeValue);
  
    cout << ans << " " << cumulativeValue << endl;
}
  
// Driver Code
int main()
{
    int arr[] = { 1, 2, 5, 6, 3 };
    int N = sizeof(arr) / sizeof(arr[0]);
  
    // Budget
    int B = 90;
    findNoOfElementsandValue(arr, N, B);
    return 0;
}


Java
// Java Program to find the optimal number of 
// elements such that the cumulative value 
// should be less than given number 
import java.util.*;
  
class GFG 
{
    static int value;
  
    // This function returns true if 
    // the value cumulative according to
    // received integer K is less than 
    // budget B, otherwise returns false
    static boolean canBeOptimalValue(int K, int arr[],
                                     int N, int B) 
    {
        // Initialize a temporary array 
        // which stores the cumulative value 
        // of the original array
        int[] tmp = new int[N];
  
        for (int i = 0; i < N; i++)
            tmp[i] = (arr[i] + K * (i + 1));
  
        // Sort the array to find the
        // smallest K values
        Arrays.sort(tmp);
  
        value = 0;
        for (int i = 0; i < K; i++)
            value += tmp[i];
  
        // Check if the value is less than budget
        return value <= B;
    }
  
    // This function prints the optimal number 
    // of elements and respective cumulative value 
    // which is less than the given number
    static void findNoOfElementsandValue(int arr[], 
                                  int N, int B)
    {
        int start = 0; // Min Value or lower bound
  
        int end = N; // Max Value or upper bound
  
        // Initialize answer as zero as 
        // optimal value may not exists
        int ans = 0;
  
        value = 0;
  
        while (start <= end)
        {
            int mid = (start + end) / 2;
  
            // If the current Mid Value is an optimal
            // value, then try to maximize it
            if (canBeOptimalValue(mid, arr, N, B)) 
            {
                ans = mid;
                start = mid + 1;
            } 
            else
                end = mid - 1;
        }
          
        // Call Again to set the corresponding 
        // cumulative value for the optimal ans
        canBeOptimalValue(ans, arr, N, B);
  
        System.out.print(ans + " " + 
                         value + "\n");
    }
  
    // Driver Code
    public static void main(String[] args) 
    {
        int arr[] = { 1, 2, 5, 6, 3 };
        int N = arr.length;
  
        // Budget
        int B = 90;
        findNoOfElementsandValue(arr, N, B);
    }
}
  
// This code is contributed by 29AjayKumar


Python3
# Python Program to find the optimal number of
# elements such that the cumulative value
# should be less than given number
value = 0
  
  
# This function returns true if the value cumulative
# according to received integer K is less than budget
# B, otherwise returns false
def canBeOptimalValue(K: int, arr: list, N: int, B: int) -> bool:
    global value
  
    # Initialize a temporary array which stores
    # the cumulative value of the original array
    tmp = [0] * N
  
    for i in range(N):
        tmp[i] = (arr[i] + K * (i + 1))
  
    # Sort the array to find the smallest K values
    tmp.sort()
  
    value = 0
    for i in range(K):
        value += tmp[i]
  
    # Check if the value is less than budget
    return value <= B
  
# This function prints the optimal number of elements
# and respective cumulative value which is less than
# the given number
def findNoOfElementsandValue(arr: list, N: int, B: int):
    global value
    start = 0 # Min Value or lower bound
  
    end = N # Max Value or upper bound
  
    # Initialize answer as zero as optimal value
    # may not exists
    ans = 0
  
    value = 0
    while start <= end:
        mid = (start + end) // 2
  
        # If the current Mid Value is an optimal
        # value, then try to maximize it
        if canBeOptimalValue(mid, arr, N, B):
            ans = mid
            start = mid + 1
        else:
            end = mid - 1
  
    # Call Again to set the corresponding cumulative
    # value for the optimal ans
    canBeOptimalValue(ans, arr, N, B)
  
    print(ans, value)
  
# Driver Code
if __name__ == "__main__":
  
    arr = [1, 2, 5, 6, 3]
    N = len(arr)
  
    # Budget
    B = 90
    findNoOfElementsandValue(arr, N, B)
  
# This code is contributed by
# sanjeev2552


C#
// C# Program to find the optimal number of 
// elements such that the cumulative value 
// should be less than given number 
using System;
  
class GFG 
{
    static int value;
  
    // This function returns true if 
    // the value cumulative according to
    // received integer K is less than 
    // budget B, otherwise returns false
    static bool canBeOptimalValue(int K, int []arr,
                                  int N, int B) 
    {
        // Initialize a temporary array 
        // which stores the cumulative value 
        // of the original array
        int[] tmp = new int[N];
  
        for (int i = 0; i < N; i++)
            tmp[i] = (arr[i] + K * (i + 1));
  
        // Sort the array to find the
        // smallest K values
        Array.Sort(tmp);
  
        value = 0;
        for (int i = 0; i < K; i++)
            value += tmp[i];
  
        // Check if the value is less than budget
        return value <= B;
    }
  
    // This function prints the optimal number 
    // of elements and respective cumulative value 
    // which is less than the given number
    static void findNoOfElementsandValue(int []arr, 
                                  int N, int B)
    {
        int start = 0; // Min Value or lower bound
  
        int end = N; // Max Value or upper bound
  
        // Initialize answer as zero as 
        // optimal value may not exists
        int ans = 0;
  
        value = 0;
  
        while (start <= end)
        {
            int mid = (start + end) / 2;
  
            // If the current Mid Value is an optimal
            // value, then try to maximize it
            if (canBeOptimalValue(mid, arr, N, B)) 
            {
                ans = mid;
                start = mid + 1;
            } 
            else
                end = mid - 1;
        }
          
        // Call Again to set the corresponding 
        // cumulative value for the optimal ans
        canBeOptimalValue(ans, arr, N, B);
  
        Console.Write(ans + " " + 
                    value + "\n");
    }
  
    // Driver Code
    public static void Main(String[] args) 
    {
        int []arr = { 1, 2, 5, 6, 3 };
        int N = arr.Length;
  
        // Budget
        int B = 90;
        findNoOfElementsandValue(arr, N, B);
    }
}
  
// This code is contributed by Rajput-Ji


输出:

4 54

时间复杂度:O(N *(log N) 2 ),其中N是给定数组中元素的数量。