给定一个由N个正整数组成的数组A和一个预算B。您的任务是确定要从数组中选取的元素的最大数量,以使所有选取的元素的累积成本小于或等于预算B。第i个元素由下式给出:A [i] +(i * K)其中,K是一个常数,其值等于选取的元素数。索引(i)是基于1的。打印最大数量及其各自的累计成本。
例子:
Input : arr[] = { 2, 3, 5 }, B = 11
Output : 2 11
Explanation : Cost of picking maximum elements = {2 + (1 * 2) } + {3 + (2 * 2)} = 4 + 7 = 11 (which is equal to budget)
Input : arr[] = { 1, 2, 5, 6, 3 }, B = 90
Output : 4 54
先决条件:二进制搜索
方法:这里的想法是对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是给定数组中元素的数量。