东东的软件项目 (二分+动规)(模拟赛)

东东的软件项目(work.pas/.c/.cpp)
题目描述
东东在东东爸的培养下,终于事业有成——现在担任软件公司的ce0。
东东公司刚刚接了两个项目,这两个项目都由M个子项目组成,对于同一个项目,每个子项目都是相互独立且工作量相当的,这样分配给程序员子项目时,程序员才不会有怨言。东东手下有N名程序员可以分配给这两个项目。由于程序员水平参差不齐,完成不同项目的子项目的时间也不相同,但是同一个程序员完成同一个项目的不同子项目的时间是相同的。要求每个子项目必须由一名程序员来完成,不同的程序员可以同时做同一个项目中的不同子项目。
一个项目必须在M个子项目全部完成后才算整个项目完成。求最小的时间T,使得东东的公司能在T时间内完成两个项目。
输入格式
第一行两个正整数N,M。
接下来N行,每行包含两个整数x、y。分别表示每个程序员完成第一个项目的子程序的时间和完成第二个项目子程序的时间。
输出格式
输出最小的时间T。
样例输入
3 20
1 1
2 4
1 6
样例输出
18
样例解释
第一个人做18个项目2,耗时18;第二个人做2个项目1,2个项目2共耗时12;第三个人做18个项目1,耗时18。
数据范围与约定
对于30%的数据,1<=N、M<=30
对于50%的数据,1<=N、M<=60
对于100%的数据,1<=N、M<=100, 1<=x、y<=100

f[i][j]代表到前i个人,在项目1做了j个的情况下,项目2能做的最多的个数。转移为:f[i][j]=max{ f[i][j] , f[i-1][j-k] + (ans-k*A[i])/B[i] }

program mys;

var i,j,k,m,n,l,r,mid:longint;
x,y:array[0..300000]of longint;
f:array[0..200,0..200]of longint;

function max(a,b:longint):longint;
begin 
if a>b then exit(a)
else exit(b);
end;

function pd(t:longint):boolean;
var i,j,k:longint;
begin 
fillchar(f,sizeof(f),$9f);
f[0,0]:=0;
for i:=1 to n do 
for j:=0 to m do 
for k:=0 to j do 
if (j-k)*x[i]>t then continue 
else
f[i,j]:=max(f[i,j],f[i-1,k]+(t-((j-k)*x[i]))div y[i]);
if f[n,m]>=m then exit(true)
else exit(false);
end;

begin 
assign(input,'work.in'); reset(input);
assign(output,'work.out'); rewrite(output);
readln(n,m);
for i:=1 to n do 
readln(x[i],y[i]);
l:=0; r:=1000000;
repeat
mid:=(l+r) div 2;
if pd(mid) then r:=mid-1
else l:=mid+1;
until l>r;
writeln(l);
close(input);
close(output);
end.

你可能感兴趣的:(动态规划,二分答案)