POJ 1275 Cashier Employment 出纳员问题 差分约束系统

题目:

Tehran 的一家每天24 小时营业的超市,需要一批出纳员来满足它的需要。超市经理雇
佣你来帮他解决他的问题——超市在每天的不同时段需要不同数目的出纳员(例如:午夜时
只需一小批,而下午则需要很多)来为顾客提供优质服务。他希望雇佣最少数目的出纳员。
经理已经提供你一天的每一小时需要出纳员的最少数量——R(0), R(1), ..., R(23)。
R(0)表示从午夜到上午1:00 需要出纳员的最少数目,R(1)表示上午1:00 到2:00
之间需要的,等等。每一天,这些数据都是相同的。有N 人申请这项工作,每个申请者I
在没24 小时中,从一个特定的时刻开始连续工作恰好8 小时,定义tI (0 <= tI <= 23)
为上面提到的开始时刻。也就是说,如果第I 个申请者被录取,他(她)将从tI 时刻开始
连续工作8 小时。
你将编写一个程序,输入R(I)(I = 0..23)和tI (I = 1..N),它们都是非负整数,
计算为满足上述限制需要雇佣的最少出纳员数目。在每一时刻可以有比对应的R(I)更多
的出纳员在工作。

分析


附上代码:

const
  maxn=1000;


type
  node=record
  fromv,endv,v:longint;
end;


var
  n,m,n1,temp:longint;
  elist:array [1..maxn] of node;
  t,value,data:array [-1..maxn] of longint;


procedure add(x,y,z:longint);
begin
  inc(m);
  with elist[m] do
    begin
      fromv:=x; endv:=y; v:=z;
    end;
end;


procedure init;
var
  i,x:longint;
begin
  for i:=0 to 23 do
    read(value[i]);
  readln;
  readln(n);
  fillchar(t,sizeof(t),0);
  for i:=1 to n do
    begin
      readln(x);
      inc(t[x]);
    end;
end;


procedure main;
var
  i,j,min:longint;
  check:boolean;
begin
  for min:=1 to n do
    begin
      m:=0;
      for i:=-1 to 23 do
        data[i]:=maxn*maxn;
      add(23,-1,-min);
      for i:=0 to 23 do
        begin
          add(i,i-1,0); add(i-1,i,t[i]);
          if i>7 then
            add(i,i-8,-value[i])
          else
            add(i,i+16,-value[i]+min);
        end;
      for j:=0 to 23 do
        begin
          check:=true;
          for i:=1 to m do
             with elist[i] do
               if data[endv]>data[fromv]+v then
                 begin
                   data[endv]:=data[fromv]+v;
                   check:=false;
                 end;
          if check then
            break;
        end;
      check:=true;
      for i:=1 to m do
        with elist[i] do
          if data[endv]>data[fromv]+v then
            begin
              check:=false;
              break;
            end;
      if check then
        begin
          writeln(min);
          exit;
        end;
    end;
  writeln('No Solution');
end;


begin
  readln(n1);
  for temp:=1 to n1 do
    begin
      init;
      main;
    end;
end.

你可能感兴趣的:(差分约束系统)