题意:有m门需要过的课程,n天的时间可以选择复习、考试(如果的d[i]为0则只能复习),一门课至少要复习a[i]天才能通过(可以不连续的复习得到a[i]),问最早什么时候可以把所有课程都通过,如果不能输出-1。
1 ≤ n, m ≤ 10^5)
思路:贪心思想可知每门课尽可能拖到最后考是最优方案,这样复习的天数就最多
二分答案验证是否可行,每考一门课就把复习的总日数减去
1 var a,b,c,d:array[1..110000]of longint; 2 n,m,l,r,mid,last,i:longint; 3 4 function isok(len:longint):boolean; 5 var i,s:longint; 6 begin 7 fillchar(b,sizeof(b),0); 8 fillchar(c,sizeof(c),0); 9 for i:=len downto 1 do 10 if (a[i]>0)and(c[a[i]]=0) then 11 begin 12 b[i]:=a[i]; 13 c[a[i]]:=1; 14 end; 15 s:=0; 16 for i:=1 to len do 17 if b[i]=0 then inc(s) 18 else 19 begin 20 if d[b[i]]>s then exit(false) 21 else s:=s-d[b[i]]; 22 end; 23 for i:=1 to m do 24 if c[i]=0 then exit(false); 25 exit(true); 26 end; 27 28 begin 29 //assign(input,'cf732D.in'); reset(input); 30 //assign(output,'cf732D.out'); rewrite(output); 31 readln(n,m); 32 for i:=1 to n do read(a[i]); 33 for i:=1 to m do read(d[i]); 34 l:=1; r:=n; last:=n+1; 35 while l<=r do 36 begin 37 mid:=(l+r)>>1; 38 if isok(mid) then begin last:=mid; r:=mid-1; end 39 else l:=mid+1; 40 end; 41 if last=n+1 then writeln(-1) 42 else writeln(last); 43 //close(input); 44 //close(output); 45 end.