zoukankan      html  css  js  c++  java
  • CF 496E

    E. Distributing Parts

    You are an assistant director in a new musical play. The play consists of n musical parts, each part must be performed by exactly one actor. After the casting the director chose m actors who can take part in the play. Your task is to assign the parts to actors. However, there are several limitations.

    First, each actor has a certain voice range and there are some parts that he cannot sing. Formally, there are two integers for each actor, ci and di (ci ≤ di) — the pitch of the lowest and the highest note that the actor can sing. There also are two integers for each part — aj and bj (aj ≤ bj) — the pitch of the lowest and the highest notes that are present in the part. The i-th actor can perform the j-th part if and only if ci ≤ aj ≤ bj ≤ di, i.e. each note of the part is in the actor's voice range.

    According to the contract, the i-th actor can perform at most ki parts. Besides, you are allowed not to give any part to some actors (then they take part in crowd scenes).

    The rehearsal starts in two hours and you need to do the assignment quickly!

    Input

    The first line contains a single integer n — the number of parts in the play (1 ≤ n ≤ 105).

    Next n lines contain two space-separated integers each, aj and bj — the range of notes for the j-th part (1 ≤ aj ≤ bj ≤ 109).

    The next line contains a single integer m — the number of actors (1 ≤ m ≤ 105).

    Next m lines contain three space-separated integers each, ci, di and ki — the range of the i-th actor and the number of parts that he can perform (1 ≤ ci ≤ di ≤ 109, 1 ≤ ki ≤ 109).

    Output

    If there is an assignment that meets all the criteria aboce, print a single word "YES" (without the quotes) in the first line.

    In the next line print n space-separated integers. The i-th integer should be the number of the actor who should perform the i-th part. If there are multiple correct assignments, print any of them.

    If there is no correct assignment, print a single word "NO" (without the quotes).

    大意:

    一出戏有 n 幕, m 位演员, 每位演员有一个音域, 每幕都有声音的上下界, 一个演员能表演这一幕(一幕只有一个演员表演)当且仅当这个演员的音域能完全覆盖这一幕的音域....

    每位演员最多只能演 k 幕, 问是否存在一种方案,使得整出戏都有人表演.输出方案.

    思路:

    比较好的贪心....

    刚开始的想法是先选,不行就从前面进行"撤销操作"....发现根本写不出...

    后来无奈看题解..... 恍然大悟...

    将演员和每一幕的音域混合排序... 由于 l 是递增的,所以只要从以前的演员中找出一个最接近这个即可,为什么这个最优呢?

    因为这个最矮,所以高的能留给后面,因为 l 递增, 所以后面的都能够匹配.

    维护信息我用了multimap...P党 呵呵.

     1 #include<cstdlib>
     2 #include<cstdio>
     3 #include<algorithm>
     4 #include<map>
     5 #include<iostream>
     6 using namespace std;
     7 const int maxn = (int)1.5e5;
     8 struct S{
     9     int l,r,tp,id;
    10 }seg[maxn * 2];
    11 int n,m,i,j,tot;
    12 int remain[maxn],finish[maxn * 2],belong[maxn];
    13 multimap<int,int>M;
    14 multimap<int,int>::iterator it;
    15 int cmp(S a, S b){
    16     if(a.l != b.l) return a.l < b.l;
    17     if(a.tp != b.tp) return a.tp < b.tp;
    18     return a.r < b.r;
    19 }
    20 int main()
    21 {
    22     freopen("E.in","r",stdin);
    23     freopen("E.out","w",stdout);
    24     ios::sync_with_stdio(false);
    25     cin >> n;
    26     for(i = 1; i <= n; ++i){
    27         tot++;
    28         cin >> seg[tot].l >> seg[tot].r;
    29         seg[tot].tp = 2; seg[tot].id = i;
    30     }
    31     cin >> m;
    32     for(i = 1; i <= m; ++i){
    33         tot++;
    34         cin >> seg[tot].l >> seg[tot].r >> remain[i];
    35         seg[tot].tp = 1; seg[tot].id = i;
    36     }
    37     sort(seg+1,seg+tot+1,cmp);
    38     for(i = 1; i <= tot; ++i){
    39         if(finish[i]) continue;
    40         if(seg[i].tp == 1){
    41             if(remain[seg[i].id]) M.insert(make_pair(seg[i].r,seg[i].id));
    42         }
    43         else{
    44             if((it = M.lower_bound(seg[i].r)) != M.end()){
    45                 belong[seg[i].id] = it->second, remain[it->second]--;
    46                 if(remain[it->second] == 0) M.erase(it);
    47             }
    48             else cout << "NO
    ", exit(0);
    49         }
    50     }
    51     cout << "YES
    ";
    52     for(int i = 1; i <= n; ++i) cout << belong[i] << " ";
    53     return 0;
    54 }
    View Code
  • 相关阅读:
    重拾web开发JavaScript复习
    Linq GroupBy
    Gotchas 31对目标类型为指涉物为常量的指针类型的类型转换的认识误区
    感谢你遇到的问题
    IDisposable模式的一点理解
    感谢你遇到的问题(2)
    .Net通过OutLook发送邮件,附件的名称太长会显示乱码
    深度学习利器之自动微分(1)
    建议转载的发在文章(Aticles)而不是随笔(Posts)内
    Forum,ForumGroup和my forum的汉译
  • 原文地址:https://www.cnblogs.com/Mr-ren/p/4224781.html
Copyright © 2011-2022 走看看