您的位置:首页 > 理论基础

【Vijos1534】高性能计算机(DP)

2016-12-06 21:11 232 查看

题意:有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.

 

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: