修改得让我郁闷的一题——Vijos1048

Ronice 发表于 2006-11-17 20:58:30

哎,一直以为算法错了,到后来才发现是变量错了,该回溯的没有回溯,该-1的没有-1,下面是我的剪枝:
在DFS过程中 sum+rem[i]<max then exit; 好多大牛都说过了,但还是要说一遍,哈哈哈哈~~~  (T_T终于AC了,痛苦了一个晚上,事实证明:细节决定成败)
这是AC的代码:
var n,i,max,x,y:longint;
    s,node,w,ans:array[0..100] of integer;
    a:array[1..100,1..100] of boolean;

procedure swap(n1,n2:longint);
var t:longint;
begin
  t:=node[n1]; node[n1]:=node[n2]; node[n2]:=t;
end;
function partition(l,r:longint):longint;
  var i,j:Longint;
begin
  i:=random(r-l+1)+l;
  swap(i,r);
  j:=l-1;
  for i:=l to r-1 do
    if w[node[i]]<w[node[r]] then begin
      inc(j);
      swap(j,i)
    end;
  swap(j+1,r);
  exit(j+1);
end;
procedure qsort(l,r:longint);
  var pr:longint;
begin
  if l<r then begin
    pr:=partition(l,r);
    qsort(l,pr-1);
    qsort(pr+1,r);
  end;
end;

function can(k,x:integer):boolean;
  var j:integer;
begin
  for j:=1 to k do
    if a[ans[j],x] then exit(false);
  exit(true);
end;
procedure search(m,k,sum:longint);
  var i:integer;
begin
  for i:=m downto 1 do begin
    if sum+s[i]<max then exit;
    if can(k,node[i]) then begin
      ans[k+1]:=node[i];
      if sum+w[node[i]]>max then max:=sum+w[node[i]];
      search(i-1,k+1,sum+w[node[i]]);
    end;
  end;
end;

begin
  readln(n);
  for i:=1 to n do begin
    read(w[i]);
    node[i]:=i;
  end;
  readln;
  qsort(1,n);
  while not(eof) do begin
    readln(x,y);
    a[x,y]:=true; a[y,x]:=true;
  end;
  s[0]:=0;
  for i:=1 to n do
    s[i]:=s[i-1]+w[node[i]];
  max:=w[node[n]];
  for i:=n downto 1 do begin
    fillchar(ans,sizeof(ans),0);
    ans[1]:=node[i];
    search(i-1,1,w[ans[1]]);
    if max>s[i-1] then break;
  end;
  writeln(max);
end.

以下是各种白痴错误类型:

第一次:
var n,i,max,x,y:longint;
s,node,w,ans:array[0..100] of integer;
a:array[1..100,1..100] of boolean;

procedure swap(n1,n2:longint);
var t:longint;
begin
t:=node[n1]; node[n1]:=node[n2]; node[n2]:=t;
end;
function partition(l,r:longint):longint;
var i,j:Longint;
begin
i:=random(r-l+1)+l;
swap(i,r);
j:=l-1;
for i:=l to r-1 do
if w[node[i]]<w[node[r]] then begin
inc(j);
swap(j,i)
end;
swap(j+1,r);
exit(j+1);
end;
procedure qsort(l,r:longint);
var pr:longint;
begin
if l<r then begin
pr:=partition(l,r);
qsort(l,pr-1);
qsort(pr+1,r);
end;
end;

function can(k,x:integer):boolean;
var j:integer;
begin
for j:=1 to k do
if a[ans[j],x] then exit(false);
exit(true);
end;
procedure search(m,k,sum:longint);
var i:integer;
begin
for i:=m downto 1 do begin
if sum+s[i]<max then exit;
if can(k,node[i]) then begin
inc(k); ans[k]:=node[i];
if sum+w[ans[k]]>max then max:=sum+w[ans[k]];
search(i-1,k,sum+w[ans[k]]);
end;
end;
end;

begin
readln(n);
for i:=1 to n do begin
read(w[i]);
node[i]:=i;
end;
readln;
qsort(1,n);
while not(eof) do begin
readln(x,y);
a[x,y]:=true; a[y,x]:=true;
end;
s[0]:=0;
for i:=1 to n do
s[i]:=s[i]+w[node[i]];
max:=w[node[n]];
for i:=n downto 1 do begin
fillchar(ans,sizeof(ans),0);
ans[1]:=node[i];
search(i-1,1,w[ans[1]]);
if max>s[i-1] then break;
end;
writeln(max);
end.
有一个低级错误,找了好久才发现的不知道谁眼尖马上看出来了,看不出来对比一下下面的程序:
第二次:
var n,i,max,x,y:longint;
s,node,w,ans:array[0..100] of integer;
a:array[1..100,1..100] of boolean;

procedure swap(n1,n2:longint);
var t:longint;
begin
t:=node[n1]; node[n1]:=node[n2]; node[n2]:=t;
end;
function partition(l,r:longint):longint;
var i,j:Longint;
begin
i:=random(r-l+1)+l;
swap(i,r);
j:=l-1;
for i:=l to r-1 do
if w[node[i]]<w[node[r]] then begin
inc(j);
swap(j,i)
end;
swap(j+1,r);
exit(j+1);
end;
procedure qsort(l,r:longint);
var pr:longint;
begin
if l<r then begin
pr:=partition(l,r);
qsort(l,pr-1);
qsort(pr+1,r);
end;
end;

function can(k,x:integer):boolean;
var j:integer;
begin
for j:=1 to k do
if a[ans[j],x] then exit(false);
exit(true);
end;
procedure search(m,k,sum:longint);
var i:integer;
begin
for i:=m downto 1 do begin
if sum+s[i]<max then exit;
if can(k,node[i]) then begin
inc(k); ans[k]:=node[i];
if sum+w[ans[k]]>max then max:=sum+w[ans[k]];
search(i-1,k,sum+w[ans[k]]);
end;
end;
end;

begin
readln(n);
for i:=1 to n do begin
read(w[i]);
node[i]:=i;
end;
readln;
qsort(1,n);
while not(eof) do begin
readln(x,y);
a[x,y]:=true; a[y,x]:=true;
end;
s[0]:=0;
for i:=1 to n do
s[i]:=s[i-1]+w[node[i]];
max:=w[node[n]];
for i:=n downto 1 do begin
fillchar(ans,sizeof(ans),0);
ans[1]:=node[i];
search(i-1,1,w[ans[1]]);
if max>s[i-1] then break;
end;
writeln(max);
end.

所有剪枝都删除的结果和第二次的一样,说明不是剪枝的问题,,
第三次:
var n,i,max,x,y:longint;
s,node,w,ans:array[0..100] of integer;
a:array[1..100,1..100] of boolean;

procedure swap(n1,n2:longint);
var t:longint;
begin
t:=node[n1]; node[n1]:=node[n2]; node[n2]:=t;
end;
function partition(l,r:longint):longint;
var i,j:Longint;
begin
i:=random(r-l+1)+l;
swap(i,r);
j:=l-1;
for i:=l to r-1 do
if w[node[i]]<w[node[r]] then begin
inc(j);
swap(j,i)
end;
swap(j+1,r);
exit(j+1);
end;
procedure qsort(l,r:longint);
var pr:longint;
begin
if l<r then begin
pr:=partition(l,r);
qsort(l,pr-1);
qsort(pr+1,r);
end;
end;

function can(k,x:integer):boolean;
var j:integer;
begin
for j:=1 to k do
if a[ans[j],x] then exit(false);
exit(true);
end;
procedure search(m,k,sum:longint);
var i:integer;
begin
for i:=m downto 1 do begin
if can(k,node[i]) then begin
inc(k); ans[k]:=node[i];
search(i-1,k,sum+w[ans[k]]);
end;
end;
if sum>max then max:=sum;
end;

begin
readln(n);
for i:=1 to n do begin
read(w[i]);
node[i]:=i;
end;
readln;
qsort(1,n);
while not(eof) do begin
readln(x,y);
a[x,y]:=true; a[y,x]:=true;
end;
s[0]:=0;
for i:=1 to n do
s[i]:=s[i-1]+w[node[i]];
max:=w[node[n]];
for i:=n downto 1 do begin
fillchar(ans,sizeof(ans),0);
ans[1]:=node[i];
search(i-1,1,w[ans[1]]);
end;
writeln(max);
end.

哪位牛路过,就顺便指点迷津阿,,弄出来了,是因为k的变量……
k改变了can(k,node[i])也改变了,前车之鉴阿  细心细心……
关键词(Tag): vijos


收藏: QQ书签 del.icio.us 订阅: Google 抓虾

最新评论

发表评论

* 昵称

已经注册过? 请登录

新用户请先注册 以便能显示头像及追踪评论回复

Email
网址
* 评论
表情
 
 

分类小组论坛
杂谈, 娱乐、八卦, 文学、艺术, 体育, 旅游、同城, 象牙塔, 情感, 时尚、生活, 星座, 科技

请注意遵守中华人民共和国法律法规, 如威胁到本站生存, 将依法向有关部门报告, 同时本站的相关记录可能成为对您不利的证据.

相关法律法规
全国人大常委会关于维护互联网安全的决定
中华人民共和国计算机信息系统安全保护条例
中华人民共和国计算机信息网络国际联网管理暂行规定
计算机信息网络国际联网安全保护管理办法
计算机信息系统国际联网保密管理规定