我采用的是dfsid搜索每一个rail来源的board。以下技巧都是针对这种搜索顺序来制定的。
(注:rail是所需要切成的东西,board是供应商提供的原料)
加上上述优化策略后,程序就能很快出解了。
代码:
{ ID: ymwbegi1 PROG: fence8 LANG: PASCAL } var n,i,m,tot,ans,l,r,mid,j,rubbish:longint; flag:boolean; a,b,s,c:array[0..2000] of longint; procedure sort; var i,j:longint; begin for i:=1 to n-1 do for j:=i+1 to n do if a[i]>a[j] then begin a[0]:=a[i];a[i]:=a[j];a[j]:=a[0]; end; for i:=1 to m-1 do for j:=i+1 to m do if b[i]<b[j] then begin b[0]:=b[i];b[i]:=b[j];b[j]:=b[0]; end; end; procedure dfs(x,y:longint); var i:longint; begin if x>m then begin flag:=true; exit; end; if rubbish>tot-s[m]+s[mid-1] then exit; if s[m]-s[x-1]>tot-s[x-1]+s[mid-1] then exit; for i:=y to n do if a[i]>=b[x] then begin a[i]:=a[i]-b[x]; if a[i]<b[m] then inc(rubbish,a[i]); if b[x]=b[x+1] then dfs(x+1,i) else dfs(x+1,1); if a[i]<b[m] then dec(rubbish,a[i]); a[i]:=a[i]+b[x]; if flag then exit; end; end; begin assign(input,'fence8.in'); assign(output,'fence8.out'); reset(input); rewrite(output); readln(n); for i:=1 to n do begin readln(a[i]); tot:=tot+a[i]; end; readln(m); c:=a; for i:=1 to m do readln(b[i]); sort; for i:=1 to m do s[i]:=s[i-1]+b[i]; l:=1; r:=m; while s[m]-s[l-1]>tot do inc(l); while l<=r do begin mid:=(l+r) div 2; flag:=false; rubbish:=0; a:=c; dfs(mid,1); if flag then begin ans:=m-mid+1; r:=mid-1; end else l:=mid+1; end; writeln(ans); close(input); close(output); end.