首先,我们可以先求出每个员工与其他员工的距离,即离他最近的发工资的员工的距离。

对于员工 i,我们可以维护一个数组 dist,dist[j]表示员工 i 和员工 j 之间的距离。初始时,我们可以将 dist 数组的所有元素初始化为无穷大,表示员工 i 与其他员工之间的距离尚未确定。

然后,我们可以遍历 m 名发工资的员工 b_1, b_2, ..., b_m,并更新 dist 数组。对于每个员工 b_i,我们将其与所有其他员工的距离更新为 min(dist[j], abs(b_i - j)),表示员工 b_i 与员工 j 的距离为 min(dist[j], abs(b_i - j))。

接下来,我们可以使用二分查找的方法来确定最小的工资 k。我们可以假设工资的上界为 max(a_1, a_2, ..., a_n),下界为 0,然后在这个范围内进行二分查找。

对于每个工资的候选值 mid,我们可以遍历所有员工,计算每个员工的快乐值增加量。对于员工 i,如果他的期望快乐值 a_i 大于等于当前工资候选值 mid,那么他的快乐值增加量为 k。否则,他的快乐值增加量为 max(0, k - dist[i])。

最后,如果所有员工的快乐值增加量之和大于等于 0,说明当前工资候选值 mid 可以满足所有员工的期望快乐值,我们可以将上界更新为 mid。否则,我们将下界更新为 mid + 1。

最终,当上界等于下界时,我们找到了最小的工资 k,使得所有员工的快乐值不低于他们的期望快乐值。

下面是使用 C++ 实现的代码:

#include <iostream>
#include <vector>
#include <algorithm>
#include <climits>

using namespace std;

int main() {
    int n, m;
    cin >> n >> m;
    vector<int> a(n);
    for (int i = 0; i < n; ++i) {
        cin >> a[i];
    }
    vector<int> b(m);
    for (int i = 0; i < m; ++i) {
        cin >> b[i];
    }

    vector<int> dist(n, INT_MAX);
    for (int i = 0; i < m; ++i) {
        for (int j = 0; j < n; ++j) {
            dist[j] = min(dist[j], abs(b[i] - j));
        }
    }

    int left = 0, right = *max_element(a.begin(), a.end());
    while (left < right) {
        int mid = left + (right - left) / 2;
        int happiness = 0;
        for (int i = 0; i < n; ++i) {
            if (a[i] >= mid) {
                happiness += mid;
            } else {
                happiness += max(0, mid - dist[i]);
            }
        }
        if (happiness >= accumulate(a.begin(), a.end(), 0)) {
            right = mid;
        } else {
            left = mid + 1;
        }
    }

    cout << left << endl;

    return 0;
}

在这个代码中,我们使用了二分查找的方法来确定最小的工资 k。时间复杂度为 O(n log M),其中 n 是员工数量,M 是员工期望快乐值的最大值。空间复杂度为 O(n),用于存储距离数组 dist。

注意,这个解法假设员工的编号是从 0 开始的,而不是从 1 开始的。如果从 1 开始编号,需要在代码中做相应的调整。

C++ 算法:用二分查找找到最小工资满足员工期望快乐值

原文地址: https://www.cveoy.top/t/topic/qimA 著作权归作者所有。请勿转载和采集!

免费AI点我,无需注册和登录