C. Phoenix and Towers

https://codeforces.com/problemset/problem/1515/C

题意:给定n个tower,每个tower有一个高度h,并且每个h都不超过x。现要将n个tower合并为m个tower,问能否保证合并后的m个tower最大的高度差不超过x?如果能,则输出yes,并输出分组结果,否则输出No。

思路:初始h均不超过x,说明在最开始时,任意两个tower的高度差必不超过x。在后面分组时,根据这个原则,我们总是将当前的tower加到m个tower中height最小的一个,而当前的tower不超过x,所以添加到高度最短的tower中时,即便它成为了最高的tower,它的高度也不会高于其他的tower超过x。所以采用这种贪心策略,最后输出的结果必然是YES。

总结:我觉得这种策略的本质,就是避免了连续将两个较高的tower合并在一起,从而导致了当前的tower高于其他的tower超过x。但是在看题解前,真没有任何思路,看到了题解后,也没看明白,因为没有抓住题目中最开始的重点:所有的tower最开始都不超过x。

不超过x = 任意两个差值不超过x; tower在合并时增加的数值不会超过x; 最短的tower随便加一个tower进来,都不会在高度上超过其他的tower x的数值。

inline void solve(){
    int n, m, x;
    cin >> n >> m >> x;

    vector<int> h(n);
    for (auto& x : h) {
        cin >> x;
    }

    multiset<pair<int, int>> sett;
    vector<int> ans(n);
    for (int i = 0; i < n; ++i) {
        if (sett.size() < m) {
            sett.insert({h[i], i});
            ans[i] = i;
        }
        else {
            auto [v, id] = *sett.begin();
            sett.erase(sett.begin());
            sett.insert({v + h[i], id});
            ans[i] = id;
        }
    }

    cout << "YES\n";
    for (int i = 0; i < n; ++i) {
        cout << ans[i] + 1 << " \n"[i == n - 1];
    }

}
posted @ 2025-03-15 14:43  _Yxc  阅读(24)  评论(0)    收藏  举报