1. 程式人生 > >Codeforces Round #523 (Div. 2) D. TV Shows

Codeforces Round #523 (Div. 2) D. TV Shows

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