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];
}
}

浙公网安备 33010602011771号