I and OI
Past...

题意:给出N(N<=40)根木棍,每根长度为Li(Li<=40),要用完所有的木棍构成面积最大的三角形,求最大面积.

分析:用can[i,j,k]表示用前i根木棍,组成两条长为j,k的长木棍是否可能.

can[i,j,k]=can[i,j,k] or can[i-1,j-l[i],k] or can[i-1,j,k-l[i]] or can[i-1,j,k].

最后枚举两条边,求出第三条边,用海伦公式求出面积即可.

这是比较水的算法,跑了844MS..

code:

var   can:array[0..40,0..800,0..800] of boolean;
      l:array[0..41] of longint;
      sum,n,i,j,k,tot,c:longint;
      p,s,max:real;
      maxi,maxj:longint;

      function legal(a,b,c:longint):boolean;
      begin
            if (a+b<=c)or(a+c<=b)or(b+c<=a) then exit(false);
            exit(true);
      end;

begin
      readln(n);
      for i:=1 to n do
      begin
            readln(l[i]);
            sum:=sum+l[i];
      end;
      tot:=sum;
      sum:=sum>>1;

      can[0,0,0]:=true;
      for i:=1 to n do
         for j:=0 to sum do
            for k:=0 to sum do
            begin
                  if j>=l[i] then can[i,j,k]:=can[i,j,k] or can[i-1,j-l[i],k];
                  if k>=l[i] then can[i,j,k]:=can[i,j,k] or can[i-1,j,k-l[i]];
                  can[i,j,k]:=can[i,j,k] or can[i-1,j,k];
            end;

      for i:=1 to sum do
         for j:=1 to sum do
         if can[n,i,j] then
         begin
               c:=tot-i-j;
               if not legal(i,j,c) then continue;
               p:=(i+j+c)/2;
               s:=sqrt(p*(p-i)*(p-j)*(p-c));
               if s>max then
               begin maxi:=i; maxj:=j; max:=s;  end;
         end;

      if max=0 then writeln(-1)
      else writeln(trunc(max*100));
end.
posted on 2011-08-12 15:48  exponent  阅读(508)  评论(0编辑  收藏  举报