OI教练BG在n天中每天早晨会给wxjlzbcd发一套题,其中包含A_i道题目。如果不做的话,题目会累加到下一天。
wxjlzbcd每天能够刷掉的题目数量为B_i,BG的题目数量太少,可能不能满足wxjlzbcd每天刷题的需求,如果题目数量不够,wxjlzbcd当天就不会刷题,因为空出来的时间他有可能会浪费掉。
但是wxjlzbcd不想天天颓废,他想知道自己最多能有多少天有题刷。
输入输出格式 Input/output
输入格式:
输入第1行为一个整数n,表示天数。
第2行包括n个数字A_i,表示BG n天中每天发的题目数A_i。
第3行包括n个数字B_i,表示wxjlzbcd n天中每天能刷掉的题目数B_i。
输出格式:
输出第1行为一个整数ans,表示天数。
输入输出样例 Sample input/output
样例测试点#1 输入样例:
5
1 4 1 2 3
1 2 3 4 5
输出样例:
4
说明 description
对于40%的数据,保证1≤n≤1000;
对于100%的数据,保证1≤n≤250000,0≤a_i≤10^9,0≤b_i≤10^9。
这是一道经典的贪心题,好像被改编了的样子。。。。
理解题意是关键:这个人如果当天可以刷题的话他也可以选择不刷,因为留下今天一天的这些题目可能可以满足以后多天的需求。所以貌似想到了用堆来维护的样纸~~~
实现思路:
现在我们用a【i】记录BG每天发的题目,用b【i】记录这个人每天的需求。比较每天的需求和所发题数。能刷题的话就刷,不能刷题的话,就在之前刷过题的天中找一个需求量最大的dui【1】与这一天的需求b【i】比较,如果dui【1】>b【i】,那么就用b【i】去替换那一天,即dui【1】:=b【i】,因为这样可以留下更多的题目。
代码:
var t,tot,n:int64;
i:longint;
dui, a,b:array[1..250000]of int64;
procedure up(j:longint);
var i:longint;
begin
while (j>>1)>=1 do
begin
i:=j>>1;
if dui[i]<dui[j] then
begin
t:=dui[i];
dui[i]:=dui[j];
dui[j]:=t;
j:=i;
end
else break;
end;
end;
procedure down(i:longint);
var j:longint;
begin
while (i<<1)<=tot do
begin
j:=i<<1;
if (j<tot)and(dui[j]<dui[j+1]) then inc(j);
if dui[i]<dui[j] then
begin
t:=dui[i];
dui[i]:=dui[j];
dui[j]:=t;
i:=j;
end
else break;
end;
end;
begin
readln(n);
for i:=1 to n do read(a[i]);
for i:=1 to n do read(b[i]);
tot:=0;
for i:=1 to n do
if a[i]>=b[i] //能刷题就刷
then
begin
inc(a[i+1],a[i]-b[i]);
inc(tot);
dui[tot]:=b[i];
up(tot);
end
else
begin //不能刷就比较
if dui[1]>b[i] then
begin
inc(a[i+1],a[i]+dui[1]-b[i]);
dui[1]:=b[i];
down(1);
end
else inc(a[i+1],a[i]);
end;
write(tot);
end.
评测结果 Result
测试点 #1:通过该测试点。 得分10,耗时0ms,内存3174kB。
测试点 #2:通过该测试点。 得分10,耗时15ms,内存3166kB。
测试点 #3:通过该测试点。 得分10,耗时0ms,内存3170kB。
测试点 #4:通过该测试点。 得分10,耗时0ms,内存3178kB。
测试点 #5:通过该测试点。 得分10,耗时15ms,内存3317kB。
测试点 #6:通过该测试点。 得分10,耗时46ms,内存3633kB。
测试点 #7:通过该测试点。 得分10,耗时156ms,内存4849kB。
测试点 #8:通过该测试点。 得分10,耗时265ms,内存5926kB。
测试点 #9:通过该测试点。 得分10,耗时452ms,内存8093kB。
测试点 #10:通过该测试点。 得分10,耗时312ms,内存8138kB。