【Vijos1534】高性能计算机(DP)
题意:有NA个A与NB个B两种任务需要完成,完成一段长度为X的A任务需要时间ta+ka*x*x,B任务类似,连续的同一种任务不能分成两段运行
有P台可以并行运算的计算机,求最快完成所有任务的时间
1≤nA≤60,1≤nB≤601≤nA≤60,1≤nB≤60
1≤p≤201≤p≤20
1≤tA≤1000,1≤tB≤1000,1≤kA≤50,1≤kB≤50
思路:无聊在Vijos上随机的一道萎靡题居然花了两天查错
黑书上也有,那种写法看起来很强大,不过下次再写
两次DP,第一次dp[i,j,0/1]表示第X台机器做i单位A,j单位B,最后做的是A/B的最小时间
第二次dp[i,j]表示前X台机器做i单位A,j单位B的最小时间
其实不加优化也能过,就是在优化上调了2天,不过速度接近快了10倍
当i'>=i,j'>=j时做(i',j')的花费必定大于做(i,j)
所以dp[i-x,j-y]<f[x,y]时继续增大y必定不会更优,break即可
调了两天主要是因为程序把边界的inf当成有效数值直接就break了,导致有些有效的转移没有被用到
真是大坑
1 var f:array[0..200,0..200,1..2]of longint; 2 dp:array[0..200,0..200]of longint; 3 ta,tb,ka,kb:array[1..1000]of longint; 4 na,nb,p,i,j,k,v,x,y:longint; 5 6 function min(x,y:longint):longint; 7 begin 8 if x<y then exit(x); 9 exit(y); 10 end; 11 12 function max(x,y:longint):longint; 13 begin 14 if x>y then exit(x); 15 exit(y); 16 end; 17 18 procedure print; 19 var i,j:longint; 20 begin 21 // writeln(v); 22 // for i:=0 to na do 23 // for j:=0 to nb do writeln(dp[i,j]); 24 // writeln; 25 // end; 26 //writeln; 27 end; 28 29 begin 30 assign(input,'data.in'); reset(input); 31 assign(output,'Vijos1534.out'); rewrite(output); 32 read(na,nb); 33 read(p); 34 for i:=1 to p do read(ta[i],tb[i],ka[i],kb[i]); 35 fillchar(dp,sizeof(dp),$1f); 36 dp[0,0]:=0; 37 for v:=1 to p do 38 begin 39 fillchar(f,sizeof(f),$1f); 40 f[0,0,1]:=0; f[0,0,2]:=0; 41 for i:=0 to na do 42 for j:=0 to nb do 43 for k:=1 to 60 do 44 begin 45 if i+k<=na then f[i+k,j,1]:=min(f[i+k,j,1],f[i,j,2]+ta[v]+ka[v]*k*k); 46 if j+k<=nb then f[i,j+k,2]:=min(f[i,j+k,2],f[i,j,1]+tb[v]+kb[v]*k*k); 47 // if (i+k>na)and(j+k>nb) then break; 48 end; 49 //tmp:=dp; 50 51 for i:=na downto 0 do 52 for j:=nb downto 0 do 53 for k:=1 to 2 do 54 for x:=0 to i do 55 for y:=0 to j do 56 begin 57 dp[i,j]:=min(dp[i,j],max(dp[i-x,j-y],f[x,y,k])); 58 // writeln(i,' ',j,' ',x,' ',y,' ',k); 59 if (f[x,y,k]>dp[i-x,j-y])and(f[x,y,k]<500000000) then break; 60 end; 61 62 end; 63 writeln(dp[na,nb]); 64 // print; 65 //for i:=0 to na do 66 // for j:=0 to nb do if dp[i,j]=1359 then writeln(i,' ',j); 67 //writeln(dp[1,14]); 68 close(input); 69 close(output); 70 end.
null