jzoj P1286 太空电梯

来源:互联网 发布:网络发言防和谐器 编辑:程序博客网 时间:2024/04/27 18:13

题目大意:
奶牛们想用K中石块制造一个太空电梯去太空旅行,每种石块有自己的高度h_i和数量c_i,为了避免宇宙射线的干扰,每种石块不能超过最高可以达到的高度a_i。求奶牛能用石块堆积的最高的太空电梯

1<=K<=400
1<=c_i<=10
1<=h_i<=100
1<=a_i<=40000

题解:
排序+枚举:
这题很明显先要用a[i]排序,因为这样使得a[i]变成升序,结果就能前面完全影响后面,而如果一大一小一大,枚举就就出错。
设f[i,j]表示前i个块石头中j这个数是否出现过,1为出现过,0即为没有
//是排完序后的石头顺序

然后推
i从1 to k
j从a[i] downto 0 //顺着的话要开二维,不然逆推就可以优化掉一个维度
k从1 to c[i] //先判断j是否出现过,再进行,即f[j]=1
然后如果j+k*h[i]>a[i] //不能超过其限度
就f[j+k*h[i]]=1
最后在出现过的数中找最大值。
时间复杂度:O(Σc[i]*a[i]) //i从1到K

var   a:Array [0..401,1..3] of longint;   f:Array [0..40001] of longint;   i,j,k,n:longint;procedure qsort(l,r:longint);var   i,j,mid:longint;begin   if l>=r then exit;   mid:=a[(l+r) div 2,2];   i:=l; j:=r;   repeat        while a[i,2]<mid do inc(i);        while a[j,2]>mid do dec(j);        if i<=j then        begin             a[0]:=a[i];             a[i]:=a[j];             a[j]:=a[0];             inc(i);             dec(j);        end;   until i>j;   qsort(i,r);   qsort(l,j);end;begin    readln(n);    for i:=1 to n do      readln(a[i,1],a[i,2],a[i,3]);    qsort(1,n);    f[0]:=1;    for i:=1 to n do    begin         for j:=a[i,2] downto 0 do           if f[j]=1 then              for k:=1 to a[i,3] do              begin                   if j+k*a[i,1]>a[i,2] then break;                   f[j+k*a[i,1]]:=1;              end;    end;    for i:=a[n,2] downto 0 do      if f[i]=1 then      begin          writeln(i);          halt;      end;end.
原创粉丝点击