zoukankan      html  css  js  c++  java
  • Codeforces Round #390 (Div. 2) D. Fedor and coupons(区间最大交集+优先队列)

    http://codeforces.com/contest/754/problem/D

    题意:

    给定几组区间,找k组区间,使得它们的公共交集最大。

    思路:

    在k组区间中,它们的公共交集=k组区间中右端点最小值-k组区间中左端点最大值。如果我们要区间大,那我们应该尽量让左端点小,右端点大。

    先对区间按照左端点排序,然后用优先队列处理。

    将区间按照左端点从小到大的顺序一一进队列,只需要进右端点即可,如果此时队列内已有k个数,则队首就是这k组区间的最小右端点,而因为左端点是从小到大的顺序进队列的,所以这k组区间中左端点最大的就是当前进队列的区间,这样一来就可以算出在这种情况下的区间交集。如果此时队列内已有k+1个数,那么就弹出队首元素,因为此时弹出的区间右端点是最小的,而我们想要是的尽量大的右端点。

     1 #include<iostream>
     2 #include<algorithm>
     3 #include<cstring>
     4 #include<cstdio>
     5 #include<sstream>
     6 #include<vector>
     7 #include<stack>
     8 #include<queue>
     9 #include<cmath>
    10 #include<map>
    11 #include<set>
    12 using namespace std;
    13 typedef long long ll;
    14 typedef pair<int,int> pll;
    15 const int INF = 0x3f3f3f3f;
    16 const int maxn=3*1e5+5;
    17 
    18 int n, k;
    19 
    20 struct node
    21 {
    22     int l, r;
    23     int id;
    24     bool operator < (const node& rhs) const
    25     {
    26         return l<rhs.l || (l==rhs.l && r<rhs.r);
    27     }
    28 }p[maxn];
    29 
    30 struct cmp
    31 {
    32     bool operator() (const int a, const int b) const
    33     {
    34         return a > b;
    35     }
    36 };
    37 
    38 int main()
    39 {
    40    // freopen("in.txt","r",stdin);
    41     while(~scanf("%d%d",&n, &k))
    42     {
    43         for(int i=1; i<=n; i++)
    44         {
    45             scanf("%d%d",&p[i].l, &p[i].r);
    46             p[i].id = i;
    47         }
    48 
    49         sort(p+1,p+n+1);
    50 
    51         priority_queue<int, vector<int>, cmp > Q;
    52         int ans=0, left, right;
    53 
    54         for(int i=1;i<=n;i++)
    55         {
    56             Q.push(p[i].r);
    57             if(Q.size()>k)  Q.pop();
    58             if(Q.size()==k)
    59             {
    60                 int tmp=Q.top()-p[i].l+1;
    61                 if(tmp>ans)
    62                 {
    63                     ans=tmp;
    64                     left=p[i].l;
    65                     right=Q.top();
    66                 }
    67             }
    68         }
    69 
    70         if(ans<=0)
    71         {
    72             puts("0");
    73             for(int i=1;i<=k;i++)
    74             {
    75                 printf("%d%c",i,i==k?'
    ':' ');
    76             }
    77         }
    78         else
    79         {
    80             printf("%d
    ",ans);
    81             for(int i=1;i<=n;i++)
    82             {
    83                 if(p[i].l<=left && p[i].r>=right)
    84                 {
    85                     printf("%d",p[i].id);
    86                     k--;
    87                     if(k)  printf(" ");
    88                     else  {printf("
    ");break;}
    89                 }
    90             }
    91         }
    92     }
    93     return 0;
    94 }
  • 相关阅读:
    HDU 2089 不要62 【数位dp】
    HDU 3507 Print Article(dp+斜率优化)
    HDU 1078 FatMouse and Cheese【记忆化搜索】
    codeforces 366C Dima and Salad 【限制性01背包】
    HDU
    HDU 2844 Coins 【多重背包】(模板)
    hdu 2167 方格取数 【状压dp】(经典)
    poj 1160 Post Office 【区间dp】
    Poj
    HDU 1542 矩形面积并【离散化+线段树+扫描线】
  • 原文地址:https://www.cnblogs.com/zyb993963526/p/7080466.html
Copyright © 2011-2022 走看看