从K中减去Array值的最大值使其为0或最小值

124 阅读2分钟

从K中减去Array值的最大值,使其为0或最小值

给定两个大小为N的数组A[]B[](B[i]<A[i])和一个整数K,任务是执行**(K-A[i]+B[i])的最大次数的操作,使K变成0**或尽可能小。

注意:在任何时候都不能进行使K变成负数的操作,即如果K-A[i]是负数,就不能进行操作,任何索引都可以被尽可能多地选择。

例子。

输入。 N = 3, K = 3, A[] = {2, 3, 4}, B[] = {1, 1, 1}
输出:2
解释:对于最大圈数,
选择A[0]和B[0],所以K=3-2+1=2。
选择A[0]和B[0],所以K=2-2+1=1。
没有其他操作可能。所以最大匝数=2。

输入。 N = 2, K = 10, A[] = {5, 4} B[] ={1, 2}
输出:4

办法:这个问题可以根据以下思路来解决。

为了执行最大次数的操作,总是不断地挑选指数(例如i),使A[i]-B[i]最小。

假设这样的值是A[i]和B[i],那么对该指数进行的最大操作是**(K-B[i])/(A[i]-B[i])**[这里的K-B[i]是为了避免最后的操作,即K-A[i]是负的]

按照下面提到的步骤来实现这个想法。

  • 创建一个数组(比如v),以**(A[i]-B[i],A[i])**的形式存储数值。
  • 在**(A[i]-B[i**])的基础上以递增的顺序对数组进行排序
  • i=0到N-1的循环。
    • 如果K-v[i]的第二个值不是负数,那么用上述公式找出它的贡献(比如说x)。
    • x递增计数
  • 返回最后的计数作为答案。

下面是上述方法的实现。

C++

// C++ code to implement the approach
#include <bits/stdc++.h>
using namespace std;
// Function to calculate the maximum operations
int MakeitMin(int n,int k,int a[],int b[])
{
// Create a vector pair to store the difference
vector<pair<int,int> > v(n);
for (int i = 0; i < n; i++)
v[i] = { a[i] - b[i], a[i] };
// Sort it accordingly
sort(v.begin(), v.end());
int ans = 0;
for (int i = 0; i < n; i++) {
// Check if we can perform that turn or not
if (v[i].second > k)
continue;
// If we can perform, calculate max times
// we can perform that turn
// and add it to ans
int diff
= (k - (v[i].second - v[i].first)) / v[i].first;
ans += diff;
// Reduce the k value
k -= (diff * v[i].first);
}
return ans;
}
// Driver Code
int main()
{
int N = 2, K = 10;
int A[] = { 5, 4 };
int B[] = { 1, 2 };
cout << MakeitMin(N, K, A, B);
return 0;
}

输出

4

时间复杂度O(N * logN)
辅助空间 O(N)