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