题意
给你两种不同的工作,而每一项工作有m份。一共有n个人工作,且每个人工作两种不同的工作时间为 xi,yi ,问最小的时间是多少?(每个子项目必须由一个人一次完成,多个人可以同时做同一个项目中的不同子项目)
数据范围
对于30%的数据,n<=30.
对于60%的数据,n<=60.
对于100%的数据, n,m<=100.
分析
首先这题我们可以列出最基本的
dp
方程:
f[i,j,k]=max(f[i−1,j−s,k−t],s∗A[i]+t∗B[i])
表示第
i
个人做了
注意
要初始化,否则会出错!
总结
这题的思想归根结底还是二分,但是方程的优化是巧妙的,能又三维转成二维。
var
n,m,l,r,ma,i,mid:longint;a:array[1..190,1..2] of longint;f:array[0..100,0..100] of longint;
function max(l,r:longint):longint;
begin
if l<r then exit(r) else exit(l);
end;
function check(x:longint):boolean;
var i,j,k:longint;
begin
for i:=0 to n do
for j:=0 to m do f[i,j]:=-maxlongint;
f[0,0]:=0;
for i:=1 to n do
for j:=0 to m do
for k:=0 to j do begin
if x-k*a[i,1]<0 then break;
f[i,j]:=max(f[i,j],f[i-1,j-k]+(x-k*a[i,1]) div a[i,2]);
x:=x;
end;
if f[n,m]>=m then exit(true);exit(false);
end;
begin
assign(input,'company.in');reset(input);
assign(output,'company.out');rewrite(output);
readln(n,m);
for i:=1 to n do begin read(a[i,1],a[i,2]);ma:=max(max(ma,a[i,2]),a[i,1]);end;
l:=0;r:=ma*n;
while l<r do begin
mid:=(l+r)shr 1;
if check(mid) then r:=mid else l:=mid+1;
end;
writeln(l);
close(input);close(output);
end.