D. TV Shows
题目链接:https://codeforc.es/contest/1061/problem/D
题意:
有n个电视节目,每个电视节目都有一定的时间 [li,ri],现在要把每个节目都看了,但是电视需要租,租电视费用为x,之后每一分钟的费用为y,比如[l,r]的费用就是x+(r-l)*y。
题解:
这题依然采用贪心的思想,对于一个节目,如果在它之前存在一个最大的pr并且 (l-pr)*y<=x,那么我们现在就可以选择不租,继续沿用之前的电视。
用一个multiset来维护左边最大的pr,另外注意,当沿用了之前的电视后,相应的pr应该在集合里面删除。
具体细节见下,我之前中间过程爆int了调了好久...
#include <bits/stdc++.h> using namespace std; const int N = 1e5+5,MOD = 1e9+7; typedef long long ll; typedef pair<ll ,ll> pll; int n,x,y; ll cost[N]; pll a[N]; multiset <ll> s; int main(){ scanf("%d%d%d",&n,&x,&y); for(int i=1,l,r;i<=n;i++){ scanf("%I64d%I64d",&a[i].first,&a[i].second); s.insert(a[i].second); } sort(a+1,a+n+1); for(int i=1;i<=n;i++){ ll l=a[i].first,r=a[i].second; cost[i]=(r-l)*y+x; if(!s.size() || *s.begin()>=l) continue ; multiset <ll>:: iterator it = s.lower_bound(l); --it; ll pr = *it; if((r-pr)*y>=cost[i]) continue ;//中途可能会溢出 cost[i]=(r- pr)*y; s.erase(it); } ll ans = 0; for(int i=1;i<=n;i++){ ans+=cost[i]; ans%=MOD; } printf("%I64d",ans); return 0; }