標籤:style blog io ar color 使用 sp for on
由於m很大,所以不能使用DP。
注意到n《30,直接暴力2^n會TLE。
所以,將砝碼平均分成兩份,對一份進行一次暴力,用雜湊表存下可能的結果。
對下一份再進行一次暴力,在雜湊表中搜尋剩餘的砝碼重量是否存在,若存在則更新答案。
輸出最小答案即可。
Program CODEVS2144;const maxn=100; maxh=100007;var a:array[0..maxn] of longint; n,i,ans:longint; m:int64; h:array[0..maxh,1..2] of longint;procedure insert(x,y:longint);var hash:longint;begin hash:=x mod maxh; while (h[hash,1]<>-1) and (h[hash,1]<>x) do hash:=(hash+1) mod maxh; if h[hash,1]=-1 then begin h[hash,1]:=x; h[hash,2]:=y; end else if y<h[hash,2] then h[hash,2]:=y;end;function find(x:longint):longint;var hash:longint;begin hash:=x mod maxh; while (h[hash,1]<>-1) and (h[hash,1]<>x) do hash:=(hash+1) mod maxh; if h[hash,1]=-1 then exit(0) else exit(h[hash,2]);end;procedure dfs(x:longint;sum:int64;num:longint);begin if sum>m then exit; if x=n div 2+1 then begin insert(sum,num); exit; end; dfs(x+1,sum,num); dfs(x+1,sum+a[x],num+1);end;procedure work(x:longint;sum:int64;num:longint);var j:longint;begin if sum>m then exit; if x=n+1 then begin if sum=m then begin if num<ans then ans:=num; exit; end; j:=find(m-sum); if j<>0 then begin if j+num<ans then ans:=j+num; end; exit; end; work(x+1,sum,num); work(x+1,sum+a[x],num+1);end;begin for i:=1 to maxh do h[i,1]:=-1; readln(n,m); for i:=1 to n do readln(a[i]); ans:=maxn; dfs(1,0,0); work(n div 2+1,0,0); writeln(ans);end.
CODEVS2144 砝碼稱重2 (雜湊表)