pstopia Notes for Problem Solving Contest

[Easy] Over9000Rocks

Topcoder SRM 539 Div1

Problem

상자가 15개 이하이므로 상자들의 가능한 부분집합을 모두 살펴볼 수 있다. 부분집합에 속하는 상자들의 lower 와 upper 를 모아 더하면 그 부분집합이 만드는 돌 개수의 최소와 최대가 나온다. 부분집합마다 돌 개수의 범위를 구간으로 만들고 정렬해둔다. 앞에서부터 sweep 하면서 구간으로 덮인 좌표의 개수를 세어주면 된다. 9000을 넘는 좌표만 세어야 한다는 것을 주의하자.
#include <vector>
#include <algorithm>
using namespace std;
class Over9000Rocks {
public:
int countPossibilities(vector<int> lowerBound, vector<int> upperBound) {
vector<pair<int, int>> segs;
int n = lowerBound.size();
for (int s = 1; s < (1 << n); ++s) {
int mn = 0, mx = 0;
for (int i = 0; i < n; ++i) {
if (s & (1 << i)) {
mn += lowerBound[i];
mx += upperBound[i];
}
}
segs.emplace_back(mn, mx);
}
sort(segs.begin(), segs.end());
int prv = 9000, ans = 0;
for (const auto& seg : segs) {
if (prv < seg.first) {
ans += seg.second - seg.first + 1;
prv = seg.second;
}
else if (prv < seg.second) {
ans += seg.second - prv;
prv = seg.second;
}
}
return ans;
}
};