【NOI2008】 志愿者招募
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
志愿者招募 【问题描述】 申奥成功后,布布经过不懈努力,终于成为奥组委下属公司人力资源部门的 主管。布布刚上任就遇到了一个难题:为即将启动的奥运新项目招募一批短期志 愿者。经过估算,这个项目需要 N 天才能完成,其中第 i 天至少需要 Ai 个人。 布布通过了解得知,一共有 M 类志愿者可以招募。其中第 i 类可以从第 Si 天工 作到第 Ti 天,招募费用是每人 Ci 元。新官上任三把火,为了出色地完成自己的 工作,布布希望用尽量少的费用招募足够的志愿者,但这并不是他的特长!于是 布布找到了你,希望你帮他设计一种最优的招募方案。 【输入格式】 输入文件 employee.in 的第一行包含两个整数 N, M,表示完成项目的天数和 可以招募的志愿者的种类。 接下来的一行中包含 N 个非负整数,表示每天至少需要的志愿者人数。 接下来的 M 行中每行包含三个整数 Si, Ti, Ci,含义如上文所述。为了方便起 见,我们可以认为每类志愿者的数量都是无限多的。 【输出格式】 输入文件 employee.out 中仅包含一个整数,表示你所设计的最优方案的总费 用。 【输入样例】 33 234 122 235 332 【输出样例】 14 【样例说明】 招募 3 名第一类志愿者和 4 名第三类志愿者。 【数据规模和约定】 30%的数据中,1 ≤ N, M ≤ 10,1 ≤ Ai ≤ 10; 100%的数据中,1 ≤ N ≤ 1000,1 ≤ M ≤ 10000,题目中其他所涉及的数据均 不超过 231-1。
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 (* 2 *Problem: NOI2008 自愿者招募 3 *Author : Chen Yang 4 *Time : 2012.5.18 5 *State : 30分 6 *Memo : 搜索 7 *) 8 program employee; 9 const maxn=2020; 10 type 11 ty=record 12 x,y,v:longint; 13 end; 14 15 var 16 n,m,ans:longint; 17 g,now,cnt:array[0..maxn] of longint; 18 t:array[0..maxn] of ty; 19 //======================== 20 procedure built; 21 var 22 i,j:longint; 23 begin 24 read(n,m); 25 for i:=1 to n do read(g[i]); 26 for i:=1 to m do 27 begin 28 read(t[i].x,t[i].y,t[i].v); 29 for j:=t[i].x to t[i].y do inc(cnt[j]); 30 end; 31 end; 32 //======================== 33 procedure find(x,v:longint); 34 var 35 i,j,k,max:longint; 36 begin 37 if v>=ans then exit; 38 if x=m+1 then 39 begin 40 if ans>v then ans:=v; 41 exit; 42 end; 43 max:=0; 44 for j:=t[x].x to t[x].y do 45 begin 46 dec(cnt[j]); 47 if max<g[j] then max:=g[j]; 48 end; 49 for i:=max downto 0 do 50 begin 51 for j:=t[x].x to t[x].y do 52 begin 53 inc(now[j],i); 54 if (cnt[j]=0)and(now[j]<g[j]) then 55 begin 56 for k:=t[x].x to j do dec(now[k],i); 57 for k:=t[x].x to t[x].y do inc(cnt[k]); 58 exit; 59 end; 60 end; 61 find(x+1,v+t[x].v*i); 62 for j:=t[x].x to t[x].y do dec(now[j],i); 63 end; 64 for j:=t[x].x to t[x].y do inc(cnt[j]); 65 end; 66 //======================== 67 begin 68 assign(input,'employee.in'); reset(input); 69 assign(output,'employee.out'); rewrite(output); 70 built; 71 ans:=maxlongint; 72 find(1,0); 73 writeln(ans); 74 close(input); close(output); 75 end.
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 (* 2 *Problem: NOI2008 自愿者招募 3 *Author : Chen Yang 4 *Time : 2012.5.18 5 *State : AC 6 *Memo : 网络流 7 *) 8 program employee; 9 uses math; 10 const max=100000000; 11 maxn=2020; 12 type 13 ty1=^ty2; 14 ty2=record 15 x,f,v,fa:longint; 16 next,up:ty1; 17 end; 18 19 var 20 n,m,s,t,flow,tot,ans:longint; 21 first,fa:array[0..maxn] of ty1; 22 dui,dis,mflow:array[0..maxn] of longint; 23 get:array[0..maxn] of boolean; 24 //================== 25 procedure insert(x,y,f,v:longint); inline; 26 var 27 p,q:ty1; 28 begin 29 new(p); 30 p^.x:=y; p^.f:=f; p^.v:=v; p^.fa:=x; 31 p^.next:=first[x]; first[x]:=p; 32 new(q); 33 q^.x:=x; q^.f:=0; q^.v:=-v; q^.fa:=y; 34 q^.next:=first[y]; first[y]:=q; 35 p^.up:=q; q^.up:=p; 36 end; 37 //================== 38 procedure built; 39 var 40 i,x,y,z:longint; 41 begin 42 read(n,m); 43 s:=0; t:=n+2; y:=0; 44 for i:=1 to n do 45 begin 46 read(x); 47 if x-y>0 then begin insert(s,i,x-y,0); inc(tot,x-y); end 48 else if x-y<0 then insert(i,t,y-x,0); 49 y:=x; 50 insert(i+1,i,max,0); 51 end; 52 insert(n+1,t,x,0); 53 for i:=1 to m do 54 begin 55 read(x,y,z); 56 insert(x,y+1,max,z); 57 end; 58 end; 59 //================== 60 procedure spfa; 61 var 62 l,r,x:longint; 63 p:ty1; 64 begin 65 fillchar(get,sizeof(get),false); 66 fillchar(dis,sizeof(dis),$7); 67 fillchar(mflow,sizeof(mflow),$7); 68 l:=0; r:=1; dui[1]:=s; dis[s]:=0; 69 while l<>r do 70 begin 71 inc(l); if l>maxn then l:=0; 72 x:=dui[l]; get[x]:=false; 73 p:=first[x]; 74 while p<>nil do 75 begin 76 if (p^.f>0) and (dis[p^.x]>dis[x]+p^.v) then 77 begin 78 dis[p^.x]:=dis[x]+p^.v; mflow[p^.x]:=min(mflow[x],p^.f); 79 fa[p^.x]:=p; 80 if not get[p^.x] then 81 begin 82 get[p^.x]:=true; 83 inc(r); if r>maxn then r:=0; 84 dui[r]:=p^.x; 85 end; 86 end; 87 p:=p^.next; 88 end; 89 end; 90 inc(flow,mflow[t]); inc(ans,mflow[t]*dis[t]); 91 p:=fa[t]; 92 while p<>nil do 93 begin 94 dec(p^.f,mflow[t]); 95 inc(p^.up^.f,mflow[t]); 96 p:=fa[p^.fa]; 97 end; 98 end; 99 //================== 100 begin 101 assign(input,'employee.in'); reset(input); 102 assign(output,'employee.out'); rewrite(output); 103 built; 104 while flow<tot do spfa; 105 writeln(ans); 106 close(input); close(output); 107 end.