给定一个由N个正整数和整数K组成的数组arr [] ,任务是找到最小可能的数组总和,该总和可以通过从给定数组中重复选择一个对并将元素之一除以2并乘以得到。其他元素加2 ,最多K次。
例子:
Input: arr[] = {5, 1, 10, 2, 3}, K = 1
Output: 17
Explanation:Since K = 1, the only operation is to update arr[1] = arr[1] * 2 and arr[2] = arr[2] / 2, which modifies arr[] = {5, 2, 5, 2, 3}. Therefore, the minimum possible sum of the array that can be obtained = 17.
Input: arr[] = {50, 1, 100, 100, 1}, K = 2
Output: 154
Explanation:
Operation 1: Updating arr[1] = arr[1] * 2 and arr[3] = arr[3] / 2 modifies arr[] = {50, 2, 100, 50, 1}.
Operation 2: Updating arr[4] = arr[4] * 2 and arr[2] = arr[2] / 2 modifies arr[] = {50, 2, 50, 50, 2}.
Therefore, the minimum possible sum of the array that can be obtained = 154.
天真的方法:解决问题的最简单方法是为每个操作选择最小和最大的数组元素,然后将最小的数组元素乘以2 ,再将最大的数组元素除以2 。最后,在完成K次操作后,打印所有数组元素的总和。
下面是上述方法的实现:
C++
// C++ program to implement
// the above approach
#include
using namespace std;
// Function to find the minimum sum of
// array elements by given operations
int minimum_possible_sum(int arr[],
int n, int k)
{
// Base case
if (n == 0) {
// Return 0
return 0;
}
// Base case
if (n == 1) {
return arr[0];
}
// Perform K operations
for (int i = 0; i < k; i++) {
// Stores smallest element
// in the array
int smallest_element
= arr[0];
// Stores index of the
// smallest array element
int smallest_pos = 0;
// Stores largest element
// in the array
int largest_element = arr[0];
// Stores index of the
// largest array element
int largest_pos = 0;
// Traverse the array elements
for (int i = 1; i < n; i++) {
// If current element
// exceeds largest_element
if (arr[i] >= largest_element) {
// Update the largest element
largest_element = arr[i];
// Update index of the
// largest array element
largest_pos = i;
}
// If current element is
// smaller than smallest_element
if (arr[i] < smallest_element) {
// Update the smallest element
smallest_element = arr[i];
// Update index of the
// smallest array element
smallest_pos = i;
}
}
// Stores the value of smallest
// element by given operations
int a = smallest_element * 2;
// Stores the value of largest
// element by given operations
int b = largest_element / 2;
// If the value of a + b less than
// the sum of smallest and
// largest element of the array
if (a + b < smallest_element
+ largest_element) {
// Update smallest element
// of the array
arr[smallest_pos] = a;
// Update largest element
// of the array
arr[largest_pos] = b;
}
}
// Stores sum of elements of
// the array by given operations
int ans = 0;
// Traverse the array
for (int i = 0; i < n; i++) {
// Update ans
ans += arr[i];
}
return ans;
}
// Driver Code
int main()
{
int arr[] = { 50, 1, 100, 100, 1 };
int K = 2;
int n = sizeof(arr)
/ sizeof(arr[0]);
cout << minimum_possible_sum(
arr, n, K);
return 0;
}
Java
// Java program to implement
// the above approach
import java.util.*;
class GFG{
// Function to find the minimum sum of
// array elements by given operations
static int minimum_possible_sum(int arr[],
int n, int k)
{
// Base case
if (n == 0)
{
// Return 0
return 0;
}
// Base case
if (n == 1)
{
return arr[0];
}
// Perform K operations
for(int i = 0; i < k; i++)
{
// Stores smallest element
// in the array
int smallest_element = arr[0];
// Stores index of the
// smallest array element
int smallest_pos = 0;
// Stores largest element
// in the array
int largest_element = arr[0];
// Stores index of the
// largest array element
int largest_pos = 0;
// Traverse the array elements
for(int j = 1; j < n; j++)
{
// If current element
// exceeds largest_element
if (arr[j] >= largest_element)
{
// Update the largest element
largest_element = arr[j];
// Update index of the
// largest array element
largest_pos = j;
}
// If current element is
// smaller than smallest_element
if (arr[j] < smallest_element)
{
// Update the smallest element
smallest_element = arr[j];
// Update index of the
// smallest array element
smallest_pos = j;
}
}
// Stores the value of smallest
// element by given operations
int a = smallest_element * 2;
// Stores the value of largest
// element by given operations
int b = largest_element / 2;
// If the value of a + b less than
// the sum of smallest and
// largest element of the array
if (a + b < smallest_element +
largest_element)
{
// Update smallest element
// of the array
arr[smallest_pos] = a;
// Update largest element
// of the array
arr[largest_pos] = b;
}
}
// Stores sum of elements of
// the array by given operations
int ans = 0;
// Traverse the array
for(int i = 0; i < n; i++)
{
// Update ans
ans += arr[i];
}
return ans;
}
// Driver Code
public static void main(String[] args)
{
int arr[] = { 50, 1, 100, 100, 1 };
int K = 2;
int n = arr.length;
System.out.print(minimum_possible_sum(
arr, n, K));
}
}
// This code is contributed by susmitakundugoaldanga
Python3
# Python3 program to implement
# the above approach
# Function to find the minimum
# sum of array elements by
# given operations
def minimum_possible_sum(arr, n, k):
# Base case
if (n == 0):
# Return 0
return 0
# Base case
if (n == 1):
return arr[0]
# Perform K operations
for i in range(k):
# Stores smallest element
# in the array
smallest_element = arr[0]
# Stores index of the
# smallest array element
smallest_pos = 0
# Stores largest element
# in the array
largest_element = arr[0]
# Stores index of the
# largest array element
largest_pos = 0
# Traverse the array
# elements
for i in range(1, n):
# If current element
# exceeds largest_element
if (arr[i] >=
largest_element):
# Update the largest
# element
largest_element = arr[i]
# Update index of the
# largest array element
largest_pos = i
# If current element is
# smaller than smallest_element
if (arr[i] <
smallest_element):
# Update the smallest element
smallest_element = arr[i]
# Update index of the
# smallest array element
smallest_pos = i
# Stores the value of smallest
# element by given operations
a = smallest_element * 2
# Stores the value of largest
# element by given operations
b = largest_element // 2
# If the value of a + b less
# than the sum of smallest and
# largest element of the array
if (a + b < smallest_element +
largest_element):
# Update smallest element
# of the array
arr[smallest_pos] = a
# Update largest element
# of the array
arr[largest_pos] = b
# Stores sum of elements of
# the array by given operations
ans = 0
# Traverse the array
for i in range(n):
# Update ans
ans += arr[i]
return ans
# Driver Code
if __name__ == '__main__':
arr = [50, 1, 100, 100, 1]
K = 2
n = len(arr)
print(minimum_possible_sum(arr, n, K))
# This code is contributed by Mohit Kumar 29
C#
// C# program to implement
// the above approach
using System;
class GFG{
// Function to find the minimum sum of
// array elements by given operations
static int minimum_possible_sum(int[] arr,
int n, int k)
{
// Base case
if (n == 0)
{
// Return 0
return 0;
}
// Base case
if (n == 1)
{
return arr[0];
}
// Perform K operations
for(int i = 0; i < k; i++)
{
// Stores smallest element
// in the array
int smallest_element = arr[0];
// Stores index of the
// smallest array element
int smallest_pos = 0;
// Stores largest element
// in the array
int largest_element = arr[0];
// Stores index of the
// largest array element
int largest_pos = 0;
// Traverse the array elements
for(int j = 1; j < n; j++)
{
// If current element
// exceeds largest_element
if (arr[j] >= largest_element)
{
// Update the largest element
largest_element = arr[j];
// Update index of the
// largest array element
largest_pos = j;
}
// If current element is
// smaller than smallest_element
if (arr[j] < smallest_element)
{
// Update the smallest element
smallest_element = arr[j];
// Update index of the
// smallest array element
smallest_pos = j;
}
}
// Stores the value of smallest
// element by given operations
int a = smallest_element * 2;
// Stores the value of largest
// element by given operations
int b = largest_element / 2;
// If the value of a + b less than
// the sum of smallest and
// largest element of the array
if (a + b < smallest_element +
largest_element)
{
// Update smallest element
// of the array
arr[smallest_pos] = a;
// Update largest element
// of the array
arr[largest_pos] = b;
}
}
// Stores sum of elements of
// the array by given operations
int ans = 0;
// Traverse the array
for(int i = 0; i < n; i++)
{
// Update ans
ans += arr[i];
}
return ans;
}
// Driver Code
public static void Main()
{
int[] arr = { 50, 1, 100, 100, 1 };
int K = 2;
int n = arr.Length;
Console.WriteLine(minimum_possible_sum(
arr, n, K));
}
}
// This code is contributed by sanjoy_62
Javascript
C++
// C++ implementation of the above approach
#include
using namespace std;
// Function to find the minimum sum of
// array elements by given operations
int minimum_possible_sum(int arr[],
int n, int k)
{
// Base case
if (n == 0) {
// Return 0
return 0;
}
// Base case
if (n == 1) {
return arr[0];
}
// Stores all the array elements
// in sorted order
multiset ms;
// Traverse the array
for (int i = 0; i < n; i++) {
// Insert current element
// into multiset
ms.insert(arr[i]);
}
// Perform each operation
for (int i = 0; i < k; i++) {
// Stores smallest element
// of ms
int smallest_element
= *ms.begin();
// Stores the largest element
// of ms
int largest_element
= *ms.rbegin();
// Stores updated value of smallest
// element of ms by given operations
int a = smallest_element * 2;
// Stores updated value of largest
// element of ms by given operations
int b = largest_element / 2;
// If the value of a + b less than
// the sum of smallest and
// largest array element
if (a + b < smallest_element
+ largest_element) {
// Erase the smallest element
ms.erase(ms.begin());
// Erase the largest element
ms.erase(prev(ms.end()));
// Insert the updated value
// of the smallest element
ms.insert(a);
// Insert the updated value
// of the smallest element
ms.insert(b);
}
}
// Stores sum of array elements
int ans = 0;
// Traverse the multiset
for (int x : ms) {
// Update ans
ans += x;
}
return ans;
}
// Driver Code
int main()
{
int arr[] = { 50, 1, 100, 100, 1 };
int K = 2;
int n = sizeof(arr)
/ sizeof(arr[0]);
cout << minimum_possible_sum(
arr, n, K);
return 0;
}
Java
// Java implementation of the above approach
import java.util.*;
class GFG{
// Function to find the minimum sum of
// array elements by given operations
static int minimum_possible_sum(int arr[],
int n, int k)
{
// Base case
if (n == 0)
{
// Return 0
return 0;
}
// Base case
if (n == 1)
{
return arr[0];
}
// Stores all the array elements
// in sorted order
Vector ms = new Vector<>();
// Traverse the array
for(int i = 0; i < n; i++)
{
// Insert current element
// into multiset
ms.add(arr[i]);
}
Collections.sort(ms);
// Perform each operation
for(int i = 0; i < k; i++)
{
// Stores smallest element
// of ms
int smallest_element = ms.get(0);
// Stores the largest element
// of ms
int largest_element = ms.get(ms.size() - 1);
// Stores updated value of smallest
// element of ms by given operations
int a = smallest_element * 2;
// Stores updated value of largest
// element of ms by given operations
int b = largest_element / 2;
// If the value of a + b less than
// the sum of smallest and
// largest array element
if (a + b < smallest_element +
largest_element)
{
// Erase the smallest element
ms.remove(0);
// Erase the largest element
ms.remove(ms.size() - 1);
// Insert the updated value
// of the smallest element
ms.add(a);
// Insert the updated value
// of the smallest element
ms.add(b);
Collections.sort(ms);
}
}
// Stores sum of array elements
int ans = 0;
// Traverse the multiset
for(int x : ms)
{
// Update ans
ans += x;
}
return ans;
}
// Driver Code
public static void main(String[] args)
{
int arr[] = { 50, 1, 100, 100, 1 };
int K = 2;
int n = arr.length;
System.out.print(minimum_possible_sum(
arr, n, K));
}
}
// This code is contributed by Princi Singh
Python3
# Python3 implementation of the above approach
# Function to find the minimum sum of
# array elements by given operations
def minimum_possible_sum(arr, n, k):
# Base case
if (n == 0):
# Return 0
return 0
# Base case
if (n == 1):
return arr[0]
# Stores all the array elements
# in sorted order
ms = []
# Traverse the array
for i in range(n):
# Insert current element
# into multiset
ms.append(arr[i])
ms.sort()
# Perform each operation
for i in range(k):
# Stores smallest element
# of ms
smallest_element = ms[0]
# Stores the largest element
# of ms
largest_element = ms[-1]
# Stores updated value of smallest
# element of ms by given operations
a = smallest_element * 2
# Stores updated value of largest
# element of ms by given operations
b = largest_element / 2
# If the value of a + b less than
# the sum of smallest and
# largest array element
if (a + b < smallest_element +
largest_element):
# Erase the smallest element
ms.pop(0)
# Erase the largest element
ms.pop()
# Insert the updated value
# of the smallest element
ms.append(a)
# Insert the updated value
# of the smallest element
ms.append(b)
ms.sort()
# Stores sum of array elements
ans = int(sum(ms))
return ans
# Driver Code
arr = [ 50, 1, 100, 100, 1 ]
K = 2
n = len(arr)
print(minimum_possible_sum(arr, n, K))
# This code is contributed by rag2127
C#
// C# implementation of the above approach
using System;
using System.Collections.Generic;
class GFG
{
// Function to find the minimum sum of
// array elements by given operations
static int minimum_possible_sum(int []arr,
int n, int k)
{
// Base case
if (n == 0)
{
// Return 0
return 0;
}
// Base case
if (n == 1)
{
return arr[0];
}
// Stores all the array elements
// in sorted order
List ms = new List();
// Traverse the array
for(int i = 0; i < n; i++)
{
// Insert current element
// into multiset
ms.Add(arr[i]);
}
ms.Sort();
// Perform each operation
for(int i = 0; i < k; i++)
{
// Stores smallest element
// of ms
int smallest_element = ms[0];
// Stores the largest element
// of ms
int largest_element = ms[ms.Count - 1];
// Stores updated value of smallest
// element of ms by given operations
int a = smallest_element * 2;
// Stores updated value of largest
// element of ms by given operations
int b = largest_element / 2;
// If the value of a + b less than
// the sum of smallest and
// largest array element
if (a + b < smallest_element +
largest_element)
{
// Erase the smallest element
ms.RemoveAt(0);
// Erase the largest element
ms.RemoveAt(ms.Count - 1);
// Insert the updated value
// of the smallest element
ms.Add(a);
// Insert the updated value
// of the smallest element
ms.Add(b);
ms.Sort();
}
}
// Stores sum of array elements
int ans = 0;
// Traverse the multiset
foreach(int x in ms)
{
// Update ans
ans += x;
}
return ans;
}
// Driver Code
public static void Main(String[] args)
{
int []arr = { 50, 1, 100, 100, 1 };
int K = 2;
int n = arr.Length;
Console.Write(minimum_possible_sum(
arr, n, K));
}
}
// This code is contributed by shikhasingrajput
154
时间复杂度: O(K * N)
辅助空间: O(1)
高效方法:要优化上述方法的思想,就是使用平衡的二叉搜索树。请按照以下步骤解决问题:
- 创建一个多集(例如ms)以按排序顺序存储所有数组元素。
- 遍历数组并将所有数组元素插入ms 。
- 在每个操作中,以毫秒为单位找到最小的元素(如smallest_element)和最大的元素(如largest_element) ,并更新smallest_element = minimum_element * 2和largest_element = maximum_element / 2的值。
- 最后,遍历多重集并打印ms的所有元素的总和。
下面是上述方法的实现:
C++
// C++ implementation of the above approach
#include
using namespace std;
// Function to find the minimum sum of
// array elements by given operations
int minimum_possible_sum(int arr[],
int n, int k)
{
// Base case
if (n == 0) {
// Return 0
return 0;
}
// Base case
if (n == 1) {
return arr[0];
}
// Stores all the array elements
// in sorted order
multiset ms;
// Traverse the array
for (int i = 0; i < n; i++) {
// Insert current element
// into multiset
ms.insert(arr[i]);
}
// Perform each operation
for (int i = 0; i < k; i++) {
// Stores smallest element
// of ms
int smallest_element
= *ms.begin();
// Stores the largest element
// of ms
int largest_element
= *ms.rbegin();
// Stores updated value of smallest
// element of ms by given operations
int a = smallest_element * 2;
// Stores updated value of largest
// element of ms by given operations
int b = largest_element / 2;
// If the value of a + b less than
// the sum of smallest and
// largest array element
if (a + b < smallest_element
+ largest_element) {
// Erase the smallest element
ms.erase(ms.begin());
// Erase the largest element
ms.erase(prev(ms.end()));
// Insert the updated value
// of the smallest element
ms.insert(a);
// Insert the updated value
// of the smallest element
ms.insert(b);
}
}
// Stores sum of array elements
int ans = 0;
// Traverse the multiset
for (int x : ms) {
// Update ans
ans += x;
}
return ans;
}
// Driver Code
int main()
{
int arr[] = { 50, 1, 100, 100, 1 };
int K = 2;
int n = sizeof(arr)
/ sizeof(arr[0]);
cout << minimum_possible_sum(
arr, n, K);
return 0;
}
Java
// Java implementation of the above approach
import java.util.*;
class GFG{
// Function to find the minimum sum of
// array elements by given operations
static int minimum_possible_sum(int arr[],
int n, int k)
{
// Base case
if (n == 0)
{
// Return 0
return 0;
}
// Base case
if (n == 1)
{
return arr[0];
}
// Stores all the array elements
// in sorted order
Vector ms = new Vector<>();
// Traverse the array
for(int i = 0; i < n; i++)
{
// Insert current element
// into multiset
ms.add(arr[i]);
}
Collections.sort(ms);
// Perform each operation
for(int i = 0; i < k; i++)
{
// Stores smallest element
// of ms
int smallest_element = ms.get(0);
// Stores the largest element
// of ms
int largest_element = ms.get(ms.size() - 1);
// Stores updated value of smallest
// element of ms by given operations
int a = smallest_element * 2;
// Stores updated value of largest
// element of ms by given operations
int b = largest_element / 2;
// If the value of a + b less than
// the sum of smallest and
// largest array element
if (a + b < smallest_element +
largest_element)
{
// Erase the smallest element
ms.remove(0);
// Erase the largest element
ms.remove(ms.size() - 1);
// Insert the updated value
// of the smallest element
ms.add(a);
// Insert the updated value
// of the smallest element
ms.add(b);
Collections.sort(ms);
}
}
// Stores sum of array elements
int ans = 0;
// Traverse the multiset
for(int x : ms)
{
// Update ans
ans += x;
}
return ans;
}
// Driver Code
public static void main(String[] args)
{
int arr[] = { 50, 1, 100, 100, 1 };
int K = 2;
int n = arr.length;
System.out.print(minimum_possible_sum(
arr, n, K));
}
}
// This code is contributed by Princi Singh
Python3
# Python3 implementation of the above approach
# Function to find the minimum sum of
# array elements by given operations
def minimum_possible_sum(arr, n, k):
# Base case
if (n == 0):
# Return 0
return 0
# Base case
if (n == 1):
return arr[0]
# Stores all the array elements
# in sorted order
ms = []
# Traverse the array
for i in range(n):
# Insert current element
# into multiset
ms.append(arr[i])
ms.sort()
# Perform each operation
for i in range(k):
# Stores smallest element
# of ms
smallest_element = ms[0]
# Stores the largest element
# of ms
largest_element = ms[-1]
# Stores updated value of smallest
# element of ms by given operations
a = smallest_element * 2
# Stores updated value of largest
# element of ms by given operations
b = largest_element / 2
# If the value of a + b less than
# the sum of smallest and
# largest array element
if (a + b < smallest_element +
largest_element):
# Erase the smallest element
ms.pop(0)
# Erase the largest element
ms.pop()
# Insert the updated value
# of the smallest element
ms.append(a)
# Insert the updated value
# of the smallest element
ms.append(b)
ms.sort()
# Stores sum of array elements
ans = int(sum(ms))
return ans
# Driver Code
arr = [ 50, 1, 100, 100, 1 ]
K = 2
n = len(arr)
print(minimum_possible_sum(arr, n, K))
# This code is contributed by rag2127
C#
// C# implementation of the above approach
using System;
using System.Collections.Generic;
class GFG
{
// Function to find the minimum sum of
// array elements by given operations
static int minimum_possible_sum(int []arr,
int n, int k)
{
// Base case
if (n == 0)
{
// Return 0
return 0;
}
// Base case
if (n == 1)
{
return arr[0];
}
// Stores all the array elements
// in sorted order
List ms = new List();
// Traverse the array
for(int i = 0; i < n; i++)
{
// Insert current element
// into multiset
ms.Add(arr[i]);
}
ms.Sort();
// Perform each operation
for(int i = 0; i < k; i++)
{
// Stores smallest element
// of ms
int smallest_element = ms[0];
// Stores the largest element
// of ms
int largest_element = ms[ms.Count - 1];
// Stores updated value of smallest
// element of ms by given operations
int a = smallest_element * 2;
// Stores updated value of largest
// element of ms by given operations
int b = largest_element / 2;
// If the value of a + b less than
// the sum of smallest and
// largest array element
if (a + b < smallest_element +
largest_element)
{
// Erase the smallest element
ms.RemoveAt(0);
// Erase the largest element
ms.RemoveAt(ms.Count - 1);
// Insert the updated value
// of the smallest element
ms.Add(a);
// Insert the updated value
// of the smallest element
ms.Add(b);
ms.Sort();
}
}
// Stores sum of array elements
int ans = 0;
// Traverse the multiset
foreach(int x in ms)
{
// Update ans
ans += x;
}
return ans;
}
// Driver Code
public static void Main(String[] args)
{
int []arr = { 50, 1, 100, 100, 1 };
int K = 2;
int n = arr.Length;
Console.Write(minimum_possible_sum(
arr, n, K));
}
}
// This code is contributed by shikhasingrajput
154
时间复杂度: O(K * log 2 N)
辅助空间: O(1)