通过在每个第 i 个操作中将 2^i 添加到子集来使数组不递减所需的最小操作数
给定一个由N个整数组成的数组arr[] ,任务是通过选择数组arr[]的任何子集并添加2 i来找到使数组不递减所需的最小操作数 到第 i步子集的所有元素。
例子:
Input: arr[ ] = {1, 7, 6, 5}
Output: 2
Explanation:
One way to make the array non-decreasing is:
- Increment arr[1] and arr[3] by 20. Thereafter, the array modifies to {2, 7, 6, 6}.
- Increment arr[2] and arr[3] by 21. Thereafter, the array modifies to {2, 7, 8, 8}.
Therefore, two operations are needed to make the array non-decreasing. Also, it is the minimum count of operations.
Input: arr[ ] = {1, 2, 3, 4, 5}
Output: 0
方法:可以根据以下观察解决给定的问题:
Supposing A[] as the original array and B[] as the final, then:
- There will be only one way to make the final non-decreasing array, because there is no more than a single way to make a specific amount of addition to a number. Therefore, the task will be to minimize the max(B1−A1, B2−A2, …, Bn−An), as smaller differences lead to the use of shorter time to make the array non-decreasing.
- B[] is optimal when B[i] is the maximum value between B1, B2, …, B[i]−1 and A[i] because for each position i, B[i]−A[i] should be as small as possible and B[i-1] ≤ B[i] and A[i] ≤ B[i].
- If X operations are performed, then any array element can be increased by any integer in the range [0, 2X-1].
请按照以下步骤解决问题:
- 初始化一个变量,比如val为0 ,以存储最终数组元素与相同索引处的原始数组元素之间的最大差异。
- 初始化另一个变量,例如将mx设置为INT_MIN,以存储数组前缀的最大值。
- 使用变量i遍历数组 arr[] 并在每次迭代中将mx更新为max(mx, arr[i])并将val更新为max(val, mx – arr[i]) 。
- 2 的最大幂,小于整数val,然后将其存储在变量res中。
- 最后,完成上述步骤后,打印res的值作为答案。
下面是上述方法的实现:
C++
// C++ program for the above approach
#include
using namespace std;
// Function to count the minimum number
// of steps required to make arr non-
// decreasing
int countMinSteps(int arr[], int N)
{
// Stores differences
int val = 0;
// Stores the max number
int mx = INT_MIN;
// Traverse the array arr[]
for (int i = 0; i < N; i++) {
int curr = arr[i];
// Update mx
mx = max(mx, curr);
// Update val
val = max(val, mx - curr);
}
// Stores the result
long long res = 0;
// Iterate until 2^res-1 is less
// than val
while ((1LL << res) - 1 < val) {
++res;
}
// Return the answer
return res;
}
// Driver Code
int main()
{
// Given input
int arr[] = { 1, 7, 6, 5 };
int N = sizeof(arr) / sizeof(arr[0]);
// Function call
cout << countMinSteps(arr, N);
return 0;
}
Java
// Java program for the above approach
import java.io.*;
class GFG
{
// Function to count the minimum number
// of steps required to make arr non-
// decreasing
static int countMinSteps(int arr[], int N)
{
// Stores differences
int val = 0;
// Stores the max number
int mx = Integer.MIN_VALUE;
// Traverse the array arr[]
for (int i = 0; i < N; i++) {
int curr = arr[i];
// Update mx
mx = Math.max(mx, curr);
// Update val
val = Math.max(val, mx - curr);
}
// Stores the result
long res = 0;
// Iterate until 2^res-1 is less
// than val
while ((1 << res) - 1 < val) {
++res;
}
// Return the answer
return (int)res;
}
// Driver Code
public static void main(String[] args)
{
// Given input
int arr[] = { 1, 7, 6, 5 };
int N = arr.length;
// Function call
System.out.println(countMinSteps(arr, N));
}
}
// This code is contributed by Potta Lokesh
Python3
# Python3 program for the above approach
# Function to count the minimum number
# of steps required to make arr non-
# decreasing
def countMinSteps(arr, N):
# Stores differences
val = 0
# Stores the max number
mx = -10**9
# Traverse the array arr[]
for i in range(N):
curr = arr[i]
# Update mx
mx = max(mx, curr)
# Update val
val = max(val, mx - curr)
# Stores the result
res = 0
# Iterate until 2^res-1 is less
# than val
while ((1 << res) - 1 < val):
res += 1
# Return the answer
return res
# Driver Code
if __name__ == '__main__':
# Given input
arr = [ 1, 7, 6, 5 ]
N = len(arr)
# Function call
print(countMinSteps(arr, N))
# This code is contributed by mohit kumar 29
C#
// C# program for the above approach
using System;
using System.Collections.Generic;
class GFG{
// Function to count the minimum number
// of steps required to make arr non-
// decreasing
static int countMinSteps(int []arr, int N)
{
// Stores differences
int val = 0;
// Stores the max number
int mx = Int32.MinValue;
// Traverse the array arr[]
for (int i = 0; i < N; i++) {
int curr = arr[i];
// Update mx
mx = Math.Max(mx, curr);
// Update val
val = Math.Max(val, mx - curr);
}
// Stores the result
int res = 0;
// Iterate until 2^res-1 is less
// than val
while ((1 << res) - 1 < val) {
++res;
}
// Return the answer
return res;
}
// Driver Code
public static void Main()
{
// Given input
int []arr = { 1, 7, 6, 5 };
int N = arr.Length;
// Function call
Console.Write(countMinSteps(arr, N));
}
}
// This code is contributed by SURENDRA_GANGWAR.
Javascript
输出
2
时间复杂度: O(N)
辅助空间: O(1)