codeforces 496E Distributing Parts(贪心)

题目链接

Distributing Parts
time limit per test
2 seconds
memory limit per test
256 megabytes
input
standard input
output
standard output

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).

Sample test(s)
Input
3
1 3
2 4
3 5
2
1 4 2
2 5 1
Output
YES
1 1 2
Input
3
1 3
2 4
3 5
2
1 3 2
2 5 1
Output
NO

题意:n首歌,每首歌的最低音和最高音为ai,bi。m个人,每个人能唱的歌的最低音为ci,最高音为di,以及每个人最多唱Ki首歌。

如果cj<=ai<=bi<=dj,那么第j个人能唱第i首歌。问能不能安排m个人唱完这n首歌,如果能,输出方案。

题解:将n首歌按低音从低到高排序,将m个人按低音从低到高排序。我们先安排低音最低的那首歌,我们先找出低音小于等于该首歌的人。在这些人中只有高音大于等于该首歌高音的人才能唱这首歌,那么我们贪心的从能唱这首歌的人中,选高音最小的。这样一定是最优的,因为剩下的人的低音也一定小于后面的歌的低音,而我们选择出了满足条件的高音的最小的人,让后面的歌尽有可能的有人唱。而至于怎么找高音最小的人,我们可以用set来实现。

详情见代码:

#include<stdio.h>
#include<iostream>
#include<string.h>
#include<algorithm>
#include<string>
#include<stack>
#include<math.h>
#include<vector>
#include<set>
#define nn 110000
#define inff 0x3fffffff
#define eps 1e-8
#define mod 1000000007
typedef long long LL;
const LL inf64=LL(inff)*inff;
using namespace std;
int n,m;
struct node
{
    int l,r,id;
}a[nn];
struct node1
{
    int c,d,id;
}b[nn];
bool cmp(node xx,node yy)
{
    return xx.l<yy.l;
}
bool cmp1(node1 xx,node1 yy)
{
    return xx.c<yy.c;
}
int ans[nn];
int k[nn];
set<pair<int,int> >se;
set<pair<int,int> >::iterator it;
int main()
{
    int i;
    while(scanf("%d",&n)!=EOF)
    {
        for(i=1;i<=n;i++)
        {
            scanf("%d%d",&a[i].l,&a[i].r);
            a[i].id=i;
        }
        sort(a+1,a+n+1,cmp);
        scanf("%d",&m);
        for(i=1;i<=m;i++)
        {
            scanf("%d%d%d",&b[i].c,&b[i].d,&k[i]);
            b[i].id=i;
        }
        sort(b+1,b+m+1,cmp1);
        se.clear();
        int j=1;
        for(i=1;i<=n;i++)
        {
            while(j<=m&&b[j].c<=a[i].l)
            {
                se.insert(make_pair(b[j].d,b[j].id));
                j++;
            }
            it=se.lower_bound(make_pair(a[i].r,0));
            if((*it).first>=a[i].r)
            {
                ans[a[i].id]=(*it).second;
                k[ans[a[i].id]]--;
                if(k[ans[a[i].id]]==0)
                {
                    se.erase(*it);
                }
            }
            else
                break;
        }
        if(i<=n)
        {
            puts("NO");
        }
        else
        {
            puts("YES");
            for(i=1;i<=n;i++)
                printf("%d%c",ans[i],i==n?'\n':' ');
        }
    }
    return 0;
}



你可能感兴趣的:(ACM,贪心,greedy)