• 【BZOJ4868】期末考试(整数三分)


    题意:

    有n位同学,每位同学都参加了全部的m门课程的期末考试,都在焦急的等待成绩的公布。第i位同学希望在第ti天
    或之前得知所.有.课程的成绩。如果在第ti天,有至少一门课程的成绩没有公布,他就会等待最后公布成绩的课程
    公布成绩,每等待一天就会产生C不愉快度。对于第i门课程,按照原本的计划,会在第bi天公布成绩。有如下两种
    操作可以调整公布成绩的时间:1.将负责课程X的部分老师调整到课程Y,调整之后公布课程X成绩的时间推迟一天
    ,公布课程Y成绩的时间提前一天;每次操作产生A不愉快度。2.增加一部分老师负责学科Z,这将导致学科Z的出成
    绩时间提前一天;每次操作产生B不愉快度。上面两种操作中的参数X,Y,Z均可任意指定,每种操作均可以执行多次
    ,每次执行时都可以重新指定参数。现在希望你通过合理的操作,使得最后总的不愉快度之和最小
    1<=N,M,Ti,Bi<=100000,0<=A,B<=100000,c<=10^16
     
    思路:显然一堆线性函数之和一定是一个线性函数,整数三分即可 O(n log 1.5 n)
    O(n)做法:
     1 const oo=1<<60;
     2 var b,t:array[1..200000]of longint;
     3     n,m,i,l,r,mid,mid1,mid2:longint;
     4     a1,b1,c1,ans,s1,s2:int64;
     5 
     6 function max(x,y:longint):longint;
     7 begin
     8  if x>y then exit(x);
     9  exit(y);
    10 end;
    11 
    12 function min(x,y:int64):int64;
    13 begin
    14  if x<y then exit(x);
    15  exit(y);
    16 end;
    17 
    18 function clac(x:longint):int64;
    19 var i:longint;
    20     s,tmp:int64;
    21 begin
    22  clac:=0;
    23  for i:=1 to n do
    24   if t[i]<x then
    25   begin
    26    if x-t[i]>(oo-clac) div c1 then exit(oo);
    27    clac:=clac+c1*(x-t[i]);
    28   end;
    29 
    30 
    31  s:=0;
    32  for i:=1 to m do
    33   if b[i]<x then s:=s+x-b[i];
    34  for i:=1 to m do
    35   if b[i]>x then
    36   begin
    37    tmp:=b[i]-x;
    38    if a1<b1 then
    39    begin
    40     if s>=tmp then
    41     begin
    42      clac:=clac+a1*tmp;
    43      s:=s-tmp;
    44     end
    45      else
    46      begin
    47       clac:=clac+a1*s+b1*(tmp-s);
    48       s:=0;
    49      end;
    50    end
    51     else clac:=clac+b1*tmp;
    52   end;
    53 
    54 end;
    55 
    56 begin
    57  assign(input,'bzoj4868.in'); reset(input);
    58  assign(output,'bzoj4868.out'); rewrite(output);
    59  readln(a1,b1,c1);
    60  readln(n,m);
    61  r:=1;
    62  for i:=1 to n do
    63  begin
    64   read(t[i]);
    65   r:=max(r,t[i]);
    66  end;
    67  for i:=1 to m do
    68  begin
    69   read(b[i]);
    70   r:=max(r,b[i]);
    71  end;
    72  l:=1; ans:=1<<60;
    73  while l<=r do
    74  begin
    75   mid:=(l+r)>>1;
    76   mid1:=(l+mid)>>1; mid2:=(mid+1+r)>>1;
    77   s1:=clac(mid1); s2:=clac(mid2);
    78   ans:=min(ans,s1); ans:=min(ans,s2);
    79   if s1<=s2 then r:=mid2-1
    80    else l:=mid1+1;
    81  end;
    82  writeln(ans);
    83 
    84  close(input);
    85  close(output);
    86 end.
     
  • 相关阅读:
    【人生苦短,我学Python】个人学习笔记——str.count方法
    微信支付问题解决
    针对listview上面的按钮点击事件的操作
    Android界面之间的跳转和返回
    贪吃蛇
    数据库的连接
    Android中实现圆的面积的计算问题
    关于安卓环境的搭建问题
    python 获取cpu、内存、硬盘等实时信息 psutil
    python 配置文件
  • 原文地址:https://www.cnblogs.com/myx12345/p/6760087.html
Copyright © 2020-2023  润新知