zoukankan      html  css  js  c++  java
  • cf1061D 贪心+multiset 好题!

    cf上的思维题真好!

    本题是在模拟的基础上贪心即可:将n段时间按照左端点(右端点为第二关键字)从小到大排序,然后遍历每一个时间段。

    对于每一个时间段【li,ri】,先找到multiset中最靠近li但在li左侧的r,

    如果没有这样的r,即【li,ri】是当前最靠左的,那就需要新加一台电视机,然后把ri加入multiset

    如果找到这样的r,那就进行一次判断,如果从r到li等待时间中浪费的钱大于等于新加一台电视的钱,那就新加一台电视,把ri加入multiset

    否则就接着r往下看,那就把r从multiset中删掉,然后把新的ri加入multiset中,其实是按照时间线模拟即可!

    另外可以把所有的观看时间提取出来直接求和,两个1e9+7会爆int!

    #include<bits/stdc++.h> 
    using namespace std;
    const int N=100010 ,mod=1e9+7;
    int n,ans,x,y;
    struct node{
        int x,y;
        bool operator <(const node&A)const{
            return x == A.x ? y < A.y : x < A.x;
        }
    }a[N];
    multiset<int>s;
    multiset<int>::iterator it;
    int main(){
        scanf("%d%d%d",&n,&x,&y);
        for(int i=1;i<=n;i++){
            scanf("%d%d",&a[i].x,&a[i].y);
            ans = (ans + 1ll * y * (a[i].y - a[i].x) %mod)%mod;
        }//先把必须要看的地方加上去 
        sort(a+1,a+n+1);//时间按照左端点排序 
        for(int i=1;i<=n;i++){
            it = s.lower_bound(a[i].x);//找第一个不小于x的时间右端点 
            if(it==s.begin() || 1ll*(a[i].x-*(--it)) * y >= x){//如果所有时间的右端点都大于x,或者新加一台电视比等待的费用低,那么新加一台电视 
                ans=(ans+x)%mod;
                s.insert(a[i].y);//新加一台电视机 
            }else{
                ans=(ans+1ll*(a[i].x-*it) * y%mod)%mod;//不加电视机继续等待 
                s.erase(it);//把 上一个时间点删掉 
                s.insert(a[i].y);
            }
        }
        printf("%d
    ",ans);
        return 0;
    }
  • 相关阅读:
    【PowerDesigner】【2】将工具栏显示出来
    【PowerDesigner】【1】简单介绍
    【服务器】【Windows】【4】删除Windows系统中不想要的服务
    【Java】【8】StringUtils中isNotEmpty和isNotBlank的区别
    【Java】【7】枚举类
    hdu 1285
    Codeforces Round #198 (Div. 2) —— D
    Codeforces Round #198 (Div. 2) —— C
    Codeforces Round #198 (Div. 2) —— B
    Codeforces Round #198 (Div. 2) —— A
  • 原文地址:https://www.cnblogs.com/zsben991126/p/10050702.html
Copyright © 2011-2022 走看看