码迷,mamicode.com
首页 > 其他好文 > 详细

CODEVS2144 砝码称重2 (哈希表)

时间:2014-12-11 23:43:26      阅读:204      评论:0      收藏:0      [点我收藏+]

标签: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 (哈希表)

标签:style   blog   io   ar   color   使用   sp   for   on   

原文地址:http://www.cnblogs.com/rpSebastian/p/4158652.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!