cf1061D TV shows
题意:
把 n 个区间分成任意组,组内区间两两不交。每组的花费为 \(x+y(\)组中最右右端点-最左左端点\()\) 。求最小花费
思路:
非常草率的证明:
把区间按左端点排序。对于当前区间 \(i\) 和后面的某个区间 \(j\) ,假设前面有俩区间甲和乙,甲的右端点小于乙的右端点。有几种决策:
- \(i\) 与乙一组,\(j\) 与甲一组
- \(i\) 与甲一组,\(j\) 与乙一组
- \(i\) 与乙一组,\(j\) 新开一组
- \(i\) 新开一组,\(j\) 与乙一组
3和4对后续的影响一样,但3比较便宜。
1和2的花费是一样的,对后续其他区间的影响也一样。选1好一点。
唉反正对于每个区间,应该尝试接到一个前面的右端点最大的区间。接上去不如新开一组的话就新开
const signed N = 1e5 + 3, mod = 1e9 + 7;
ll n, x, y, ans;
PLL a[N];
signed main() {
iofast;
cin >> n >> x >> y;
for(int i = 1; i <= n; i++) cin >> a[i].fi >> a[i].se;
sort(a + 1, a + 1 + n);
priority_queue<ll, vector<ll>, greater<ll>> p; //备选r池
priority_queue<ll> q; //能选r池
for(int i = 1; i <= n; i++) {
ans += y*(a[i].se-a[i].fi) % mod;
while(p.size() && p.top() < a[i].fi) q.push(p.top()), p.pop();
if(q.size() && y*(a[i].fi-q.top())<x)
ans += y*(a[i].fi-q.top()) % mod, q.pop();
else ans += x;
p.push(a[i].se);
}
cout << ans % mod;
}

浙公网安备 33010602011771号