很容易想到dp,f[i,j,k]表示到第i根木棒所组成三条边中两条边长为j,k是否存在
之后找所有满足三角形形成条件的三条边,然后找最大;
但:
如果你朴素的写,很有可能超时,事实上,只要加一些常数优化,就能卡过去
1 var a,s:array[0..50] of longint; 2 f:array[0..1,0..2000,0..2000] of boolean; 3 i,j,k,k1,k2,n,l:longint; 4 ans,p,t:double; 5 begin 6 readln(n); 7 for i:=1 to n do 8 begin 9 readln(a[i]); 10 s[i]:=s[i-1]+a[i]; 11 end; 12 f[0,0,0]:=true; 13 k1:=1; 14 k2:=0; 15 for i:=1 to n do 16 begin 17 k1:=k1 xor 1; 18 k2:=k2 xor 1; 19 for j:=0 to s[i] do 20 begin 21 l:=min(j,s[i]-j); 22 for k:=0 to l do //常数优化1 23 begin 24 if j-a[i]>=0 then f[k2,j,k]:=f[k2,j,k] or f[k1,j-a[i],k]; 25 if k-a[i]>=0 then f[k2,j,k]:=f[k2,j,k] or f[k1,j,k-a[i]]; 26 if s[i]-j-k-a[i]>=0 then f[k2,j,k]:=f[k2,j,k] or f[k1,j,k]; 27 end; 28 end; 29 end; 30 ans:=0; 31 for i:=1 to s[n]-2 do 32 for j:=(s[n] shr 1)+1-j to min(s[n]-j-1,j) do //常数优化2:满足三角形 33 if f[k2,i,j] and (s[n]-i-j>0) then 34 begin 35 k:=s[n]-i-j; 36 if (j>=i+k) or (k>=i+j) or (i>=j+k) then continue; 37 t:=(k+i+j)/2; 38 p:=sqrt(t*(t-i)*(t-j)*(t-k)); 39 ans:=max(ans,p); 40 end; 41 if ans=0 then writeln(-1) else writeln(trunc(ans*100)); 42 end.
事实上在OI中,多加一些常数优化往往有意想不到的效果!