算法:搜索
也是比较简单的一道DFS题,主要在于剪枝上必须优化。
1.用一遍快排(从大到小),这样就确定了我们先选最大值。利用离散化确定排序后的某个数之前的序号是什么。
2.数据结构采用邻接表确定两个序号之间的不成立的关系。
3.利用一个sum数组记录sum[i]为从i~n上所有数的和。
4.然后依次从大价值选到小价值,这里剪枝优化:
一:如果当前的值再加上之后的sum[i]都无法超越ans,直接剪掉。
二:在选择价值的时候如果sum[i](即所有的数都加上)比ans小也是直接剪掉。
也是比较简单的一道DFS题,主要在于剪枝上必须优化。
1.用一遍快排(从大到小),这样就确定了我们先选最大值。利用离散化确定排序后的某个数之前的序号是什么。
2.数据结构采用邻接表确定两个序号之间的不成立的关系。
3.利用一个sum数组记录sum[i]为从i~n上所有数的和。
4.然后依次从大价值选到小价值,这里剪枝优化:
一:如果当前的值再加上之后的sum[i]都无法超越ans,直接剪掉。
二:在选择价值的时候如果sum[i](即所有的数都加上)比ans小也是直接剪掉。
此题回溯较多,注意回溯即可。
program vijos1048;
const
maxn=50;
type
atp=record
x,d:longint;
end;
var
n,ans:longint;
a:array [0..maxn] of atp;
d,sum:array [0..maxn] of longint;
b:array [0..maxn] of 0..1;
ljb:array [0..maxn,0..maxn] of longint;
procedure qsort(l,r:longint);
var
i,j,m:longint;
t:atp;
begin
i:=l;
j:=r;
m:=a[(l+r) shr 1].x;
repeat
while a[i].x>m do inc(i);
while a[j].x<m do dec(j);
if i<=j then
begin
t:=a[i];
a[i]:=a[j];
a[j]:=t;
inc(i);
dec(j);
end;
until i>j;
if i<r then qsort(i,r);
if l<j then qsort(l,j);
end;
procedure init;
var
i,x,y,t:longint;
begin
readln(n);
for i:=1 to n do
begin
read(x);
a[i].x:=x;
a[i].d:=i;
end;
qsort(1,n);
for i:=1 to n do d[a[i].d]:=i;
while not eof do
begin
readln(x,y);
x:=d[x];
y:=d[y];
if x>y then
begin
t:=x;
x:=y;
y:=t;
end;
inc(ljb[x,0]);
ljb[x,ljb[x,0]]:=y;
inc(ljb[y,0]);
ljb[y,ljb[y,0]]:=x;
end;
for i:=n downto 1 do sum[i]:=sum[i+1]+a[i].x;
end;
procedure dfs(x,now:longint);
var
i,j,tot:longint;
begin
tot:=0;
if now>ans then ans:=now;
for i:=1 to ljb[x,0] do inc(b[ljb[x,i]]);
for i:=x to n do if b[i]=0 then inc(tot,a[i].x);
if now+tot>ans then
begin
for i:=x+1 to n do
begin
if b[i]=0 then
begin
b[i]:=1;
dfs(i,a[i].x+now);
b[i]:=0;
end;
end;
end;
for i:=1 to ljb[x,0] do dec(b[ljb[x,i]]);
end;
procedure main;
var
i:longint;
begin
fillchar(b,sizeof(b),0);
ans:=0;
for i:=1 to n do
begin
if sum[i]<ans then break;
b[i]:=1;
dfs(i,a[i].x);
b[i]:=0;
end;
end;
begin
assign(input,'VJ1048.in'); reset(input);
assign(output,'VJ1048.out'); rewrite(output);
init;
main;
writeln(ans);
close(input); close(output);
end.
本文介绍了一道DFS算法题目的求解过程,重点在于通过优化剪枝策略提升算法效率。首先,使用快速排序对数据进行预处理,并离散化确定排序后的数序;其次,构建邻接表以明确序号间的关系;最后,利用sum数组记录和值,通过剪枝优化算法路径,避免无效探索。程序实现详细展示了剪枝策略的应用,包括直接跳过无法超过最优解的路径和当前路径和无法达到最优解的情况。
416

被折叠的 条评论
为什么被折叠?



