题意:
有n个电视节目,第i个电视节目的观看区间是[li,ri]
你可以同时看多台电视,但是观看区间有交集的两个电视节目不能在同一台电视上观看,
租用一台新电视需要x元,每增加一分钟需要y元
在时段[a,b]租用一台电视的费用是x+y∗(b−a)请问要看完所有电视节目至少需要多少钱。
数据范围:n<=1e5,l,r<=1e9
解法:
这题主要在于如何处理:两个不相交节目,可能用同一台电视,尽管中间会有空闲时间
因为租用一台新电视需要x元,而可能存在两个节目中间的空闲时间*y<x,这时候用同一台更优
将节目按左端点从小到大排序,遍历,在multiset找<=l的最大值(multiset存节目的右端点),
判断这两个节目连接起来的花费小还是新买一个电视的花费小即可。
code:
#include<bits/stdc++.h>
using namespace std;
#define int long long
const int maxm=1e5+5;
const int mod=1e9+7;
struct Node{
int l,r;
}a[maxm];
int n,m;
bool cmp(Node a,Node b){
if(a.l!=b.l)return a.l<b.l;
return a.r<b.r;
}
signed main(){
int n,x,y;cin>>n>>x>>y;
for(int i=1;i<=n;i++){
cin>>a[i].l>>a[i].r;
}
sort(a+1,a+1+n,cmp);
multiset<int>s;
int ans=0;
for(int i=1;i<=n;i++){
if(s.empty()){//只能买新的
s.insert(a[i].r);
ans+=x+(a[i].r-a[i].l)*y;
}else{
auto it=s.lower_bound(a[i].l);
if(it==s.begin()){//没有小于他的
s.insert(a[i].r);
ans+=x+(a[i].r-a[i].l)*y;
}else{//有小于他的
it--;//找到小于他的最大值
int link=(a[i].r-*it)*y;//连接需要的费用
int buy=x+(a[i].r-a[i].l)*y;//新买一个电视需要的费用
if(link<buy){
ans+=link;
s.erase(it);
s.insert(a[i].r);
}else{
ans+=buy;
s.insert(a[i].r);
}
}
}
ans%=mod;
}
cout<<ans<<endl;
return 0;
}