您的位置:首页 > 其它

Codeforces 377B Preparing for the Contest【二分查找+优先队列+贪心】

2016-11-29 19:13 323 查看
B. Preparing for the Contest

time limit per test
2 seconds

memory limit per test
256 megabytes

input
standard input

output
standard output

Soon there will be held the world's largest programming contest, but the testing system still has
m bugs. The contest organizer, a well-known university, has no choice but to attract university students to fix all the bugs. The university has
n students able to perform such work. The students realize that they are the only hope of the organizers, so they don't want to work for free: the
i-th student wants to get
ci 'passes' in his subjects (regardless of the volume of his work).

Bugs, like students, are not the same: every bug is characterized by complexity
aj, and every student has the level of his abilities
bi. Student
i can fix a bug j only if the level of his abilities is not less than the complexity of the bug:
bi ≥ aj, and he does it in one day. Otherwise, the bug will have to be fixed by another student. Of course, no student can work on
a few bugs in one day. All bugs are not dependent on each other, so they can be corrected in any order, and different students can work simultaneously.

The university wants to fix all the bugs as quickly as possible, but giving the students the total of not more than
s passes. Determine which students to use for that and come up with the schedule of work saying which student should fix which bug.

Input
The first line contains three space-separated integers:
n, m and
s (1 ≤ n, m ≤ 105,
0 ≤ s ≤ 109) — the number of students, the number of bugs in the system and the maximum number of passes the university is ready to give the students.

The next line contains m space-separated integers
a1,
a2, ..., am (1 ≤ ai ≤ 109) —
the bugs' complexities.

The next line contains n space-separated integers
b1,
b2, ..., bn (1 ≤ bi ≤ 109) —
the levels of the students' abilities.

The next line contains n space-separated integers
c1,
c2, ..., cn (0 ≤ ci ≤ 109) —
the numbers of the passes the students want to get for their help.

Output
If the university can't correct all bugs print "NO".

Otherwise, on the first line print "YES", and on the next line print
m space-separated integers: the
i-th of these numbers should equal the number of the student who corrects the
i-th bug in the optimal answer. The bugs should be corrected as quickly as possible (you must spend the minimum number of days), and the total given passes mustn't exceed
s. If there are multiple optimal answers, you can output any of them.

Examples

Input
3 4 9
1 3 1 2
2 1 3
4 3 6


Output
YES
2 3 2 3


Input
3 4 10
2 3 1 2
2 1 3
4 3 6


Output
YES
1 3 1 3


Input
3 4 9
2 3 1 2
2 1 3
4 3 6


Output
YES
3 3 2 3


Input
3 4 5
1 3 1 2
2 1 3
5 3 6


Output
NO


Note
Consider the first sample.

The third student (with level 3) must fix the 2nd and 4th bugs (complexities 3 and 2 correspondingly) and the second student (with level 1) must fix the 1st and 3rd bugs (their complexity also equals 1). Fixing each bug takes one day for each student, so
it takes 2 days to fix all bugs (the students can work in parallel).

The second student wants 3 passes for his assistance, the third student wants 6 passes. It meets the university's capabilities as it is ready to give at most 9 passes.

题目大意:

一共有N个人,有M个Bug,当前有S个passes.

每个人都有一个能力值bi,同时有一共雇佣值ci,雇佣这个人需要用ci个passes.每个问题有一个难度值ai。

每个人一天只能解决一个问题,而且如果对应这个人如果能够解决一个问题,需要这个人的能力值大于等于这个问题的难度值才行。

我们如果雇佣了一个人,那么这个人可以一直帮你解决Bug,但是一天只能解决一个问题。不同的人之间互不影响。

对应我们需要用最少的天数,来解决所有的Bug.如果解决不了,那么输出NO.如果能够解决掉,那么对应输出最少天数条件下的任意可行解即可。

样例1分析:

直接雇佣2号和3号.

第一天,二号解决一号问题,三号解决二号问题。

第二天,二号解决三号问题,三号解决四号问题。

共花费9.不超额度。

思路:

1、经典的二分查找的问题,很容易理解,如果我们天数越长,那么解决问题的可行性就越大,那么对应这里就有一个单调性。如果我们枚举天数来解决问题时间复杂度很大,那么对应我们使用二分查找优化这个枚举天数的问题。对应枚举的当前天数mid,如果可以在mid天内解决这M个问题,那么对应记录下来一个可行方案,同时继续在左区间继续二分过程,否则在右区间继续二分过程。

2、那么接下来我们需要贪心处理问题:

①首先将问题难度按照从大到小排序。

②然后我们将N个人按照能力值从大到小排序。

③那么接下来考虑,每次选一个人,然后让其解决最难的mid个问题(一共可以有mid天,那么对应让他每天都解决一个问题,并且因为题目难度此时排序之后是降序的,那么对应我们每次找的人都是能力值大的,肯定让其解决难题是最优的方案。).

④那么我们如果每次选一个人的时候,遍历难度值大于等于这个难度的人来寻找最小花费的人,显然时间复杂度很高,那么考虑对应优化。我们建立优先队列,队头维护的元素当然是最小花费的人。那么我们每一次对应当前问题的时候,将能够解决这个问题的人都丢到优先队列中,然后取队头,然后让队头这个人来解决mid个问题。然后进行下一个问题的判断。那么此时可以保证,队列内的所有人都一定能够解决当前问题,并且我们维护了最小花费的人。显然这样做时间复杂度就降低了很多。

⑤如果出现队列为空或者是passes剩余的量不够的时候,显然此时mid天是不够的。那么考虑接下来的二分区间。

3、注意一些代码细节即可。

Ac代码:

#include<stdio.h>
#include<string.h>
#include<algorithm>
#include<queue>
using namespace std;
struct node
{
int b,c,num;
friend bool operator <(node a,node b)
{
return a.c>b.c;
}
}r[100005],now;
struct node2
{
int a,pos;
}p[100005];
int ans[100005];
int output[100005];
int n,m,money;
int cmp(node2 tmpa,node2 tmpb)
{
return tmpa.a>tmpb.a;
}
int cmp2(node a,node b)
{
return a.b>b.b;
}
int Slove(int mid)
{
int tmp=money;
memset(ans,-1,sizeof(ans));
priority_queue<node>s;
int i=1;
int j=1;
while(i<=m)
{
while(j<=n&&r[j].b>=p[i].a)s.push(r[j]),j++;
if(s.size()==0)return 0;
now=s.top();
s.pop();
tmp-=now.c;
if(tmp<0)return 0;
int cont=0;
while(i<=m&&cont<mid)
{
ans[p[i].pos]=now.num,i++,cont++;
}
}
for(int i=1;i<=m;i++)
{
output[i]=ans[i];
}
return 1;
}
int main()
{
while(~scanf("%d%d%d",&n,&m,&money))
{
for(int i=1;i<=m;i++)
{
scanf("%d",&p[i].a);
p[i].pos=i;
}
for(int i=1;i<=n;i++)
{
scanf("%d",&r[i].b);
}
for(int i=1;i<=n;i++)
{
scanf("%d",&r[i].c);
r[i].num=i;
}
sort(p+1,p+1+m,cmp);//难度降序
sort(r+1,r+1+n,cmp2);
int flag=0;
int l=1;
int r=m;
int day;
while(r-l>=0)
{
int mid=(l+r)/2;
if(Slove(mid)==1)
{
flag=1;
day=mid;
r=mid-1;
}
else l=mid+1;
}
if(flag==1)
{
printf("YES\n");
for(int i=1;i<=m;i++)
{
printf("%d ",output[i]);
}
printf("\n");
}
else printf("NO\n");
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  Codeforces 377B