题目意思 求解是否能够到达出口 如果能 求解到达时的最大携带价值
首先使用广搜搜出包括起点和终点在内 所有特殊点之间的最短距离 建立一个隐式图
然后使用DFS枚举各个组合 然后求出最大值 注意DFS的强剪
以下是代码:
#include
<
iostream
>
#include
<
queue
>
#include
<
cmath
>
using
namespace
std;
long
Price[
20
];
long
Step[
20
][
20
];
char
Map[
60
][
60
];
long
W,H,L,M;
typedef
struct
{
long
mi,mj;
long
step;
long
from;
}Node;
queue
<
Node
>
q;
bool
hash[
60
][
60
][
20
];
long
dx[]
=
{
0
,
1
,
-
1
,
0
};
long
dy[]
=
{
1
,
0
,
0
,
-
1
};
long
b;
Node Pt[
20
];
inline
void
BFS()
{
while
(
!
q.empty())
{
q.pop();
}
memset(hash,
0
,
sizeof
(hash));
q.push(Pt[
0
]);
hash[Pt[
0
].mi][Pt[
0
].mj][Pt[
0
].from]
=
true
;
while
(
!
q.empty())
{
Node t
=
q.front();
q.pop();
long
j;
Node n;
for
(j
=
0
;j
<
4
;
++
j)
{
n.mi
=
t.mi
+
dx[j];
n.mj
=
t.mj
+
dy[j];
n.step
=
t.step
+
1
;
n.from
=
t.from;
if
(n.mi
>=
0
&&
n.mi
<
H
&&
n.mj
>=
0
&&
n.mj
<
W)
{
if
(n.step
<=
L
&&!
hash[n.mi][n.mj][n.from]
&&
Map[n.mi][n.mj]
!=
'
*
'
)
{
hash[n.mi][n.mj][n.from]
=
true
;
q.push(n);
if
(Map[n.mi][n.mj]
>=
'
A
'
&&
Map[n.mi][n.mj]
<=
'
J
'
)
{
Step[n.from][Map[n.mi][n.mj]
-
'
A
'
+
2
]
=
Step[Map[n.mi][n.mj]
-
'
A
'
+
2
][n.from]
=
n.step;
n.from
=
Map[n.mi][n.mj]
-
'
A
'
+
2
;
n.step
=
0
;
hash[n.mi][n.mj][n.from]
=
true
;
q.push(n);
}
else
if
(Map[n.mi][n.mj]
==
'
@
'
)
{
Step[n.from][
0
]
=
Step[
0
][n.from]
=
n.step;
n.from
=
0
;
n.step
=
0
;
hash[n.mi][n.mj][n.from]
=
true
;
q.push(n);
}
else
if
(Map[n.mi][n.mj]
==
'
<
'
)
{
Step[n.from][
1
]
=
Step[
1
][n.from]
=
n.step;
n.from
=
1
;
n.step
=
0
;
hash[n.mi][n.mj][n.from]
=
true
;
q.push(n);
}
}
}
}
}
}
bool
vist[
20
];
long
lmax;
long
all;
inline
void
dfs(
long
pos,
long
now,
long
step)
{
if
(lmax
==
all
||
step
>
L)
{
return
;
}
if
(Step[pos][
1
]
!=-
1
&&
step
+
Step[pos][
1
]
<=
L
&&
now
>
lmax)
{
lmax
=
now;
}
long
i;
for
(i
=
2
;i
<
M
+
2
;
++
i)
{
if
(
!
vist[i]
&&
Step[pos][i]
!=-
1
)
{
vist[i]
=
true
;
dfs(i,now
+
Price[i],step
+
Step[pos][i]);
vist[i]
=
false
;
}
}
}
int
main()
{
long
T;
scanf(
"
%ld
"
,
&
T);
b
=
1
;
while
(T
--
)
{
scanf(
"
%ld%ld%ld%ld
"
,
&
W,
&
H,
&
L,
&
M);
long
i,j;
all
=
0
;
for
(i
=
2
;i
<
M
+
2
;
++
i)
{
scanf(
"
%ld
"
,
&
Price[i]);
all
+=
Price[i];
}
Price[
0
]
=
Price[
1
]
=
0
;
gets(Map[
0
]);
for
(i
=
0
;i
<
H;
++
i)
{
gets(Map[i]);
for
(j
=
0
;j
<
W;
++
j)
{
if
(Map[i][j]
==
'
@
'
)
{
Pt[
0
].mi
=
i;
Pt[
0
].mj
=
j;
Pt[
0
].step
=
0
;
Pt[
0
].from
=
0
;
}
else
if
(Map[i][j]
>=
'
A
'
&&
Map[i][j]
<=
'
J
'
)
{
Pt[Map[i][j]
-
'
A
'
+
2
].mi
=
i;
Pt[Map[i][j]
-
'
A
'
+
2
].mj
=
j;
Pt[Map[i][j]
-
'
A
'
+
2
].step
=
0
;
Pt[Map[i][j]
-
'
A
'
+
2
].from
=
Map[i][j]
-
'
A
'
+
2
;
}
else
if
(Map[i][j]
==
'
<
'
)
{
Pt[
1
].mi
=
i;
Pt[
1
].mj
=
j;
Pt[
1
].step
=
0
;
Pt[
1
].from
=
1
;
}
}
}
memset(Step,
-
1
,
sizeof
(Step));
BFS();
if
(b
!=
1
)
{
puts(
""
);
}
printf(
"
Case %ld:\n
"
,b
++
);
if
(Step[
0
][
1
]
==-
1
||
Step[
0
][
1
]
>
L)
{
goto
l1;
}
memset(vist,
0
,
sizeof
(vist));
lmax
=-
1
;
vist[
0
]
=
true
;
dfs(
0
,
0
,
0
);
if
(lmax
!=-
1
)
{
printf(
"
The best score is %ld.\n
"
,lmax);
}
else
{
l1:
puts(
"
Impossible
"
);
}
}
return
0
;
}