为海滩和雨伞问题找到一个贪心算法

时间:2018-09-25 20:15:49

标签: algorithm greedy

一天在沙滩上。一群n人躺在沙滩上。海滩用实线R表示,第i个人的位置约为xi∈Z。您的任务是防止人们被雨伞覆盖而被晒伤。每个伞对应于一个长度为L∈N的闭合区间I = [a,a + L],如果xi∈I,则第i个人被该伞覆盖。设计一个贪婪算法,以覆盖所有人数最少的人的伞。输入由整数x1,...,xn和L组成。算法的输出应为伞的位置。 例如,如果输入为x1 = 1,x2 = 3,x3 = 5,L = 2,则最适解是放置在位置2和5的两个伞的集合,覆盖时间间隔[1、3]和[4、6]。运行时间应为n

的多项式

1 个答案:

答案 0 :(得分:0)

主要思想是,当我们看到尚未被掩盖的某人时,我们将把伞放在位置(uncoveredPersonPosition + L / 2),并且伞的覆盖范围将覆盖范围(uncoveredPersonPosition,uncoveredPersonPosition + L)。

这是这个想法的代码。

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

int solve(std::vector<double>&  people, int umbrellaCoverage) {

    std::sort(people.begin(), people.end() );

    int answer = 0;
    double umbrellaReach;

    for(const auto& p : people) {
        if(answer == 0) {
            answer += 1;
            umbrellaReach = p + umbrellaCoverage;
        }
        else {
            if(p < umbrellaReach) continue;
            else {
                answer++;
                umbrellaReach = p + umbrellaCoverage;
            }
        }
    }
    return answer;
}

int main() {

    std::vector<double> v(10);
    for(int i = 0; i < 10; ++i) v[i] = (double) i;
    std::cout << solve(v, 3) << std::endl;

    return 0;
}