Description
Input
Output
Sample Input
7 7
…….
.1###2.
.#…#.
.#.B.#.
.3…4.
..##…
……S
100
100
100
100
Sample Output
364
Data Constraint
Hint
分析:
与(jzoj 4016. 【雅礼联考DAY01】圈地为王 状压dp+bfs转移)是一样的,不过这题是在格上走,那题是在点上走。我们记录的状态可以看做是走到一个格子的最右边,所以往右边走状态要根据下一个格改变,往左走要根据起点的格子改变。
代码:
#include <iostream>
#include <cstdio>
#include <cmath>
#include <cstring>
#include <queue>
const int maxn=21;
const int dx[4]={1,0,-1,0};
const int dy[4]={0,1,0,-1};
using namespace std;
int f[maxn][maxn][256];
int n,m,cnt1,cnt2,stx,sty;
int a[maxn][maxn],v[maxn][maxn][256];
struct node{
int x,y,v;
}g[10],b[10];
struct rec{
int x,y,s;
};
queue <rec> q;
void init()
{
char s[30];
scanf("%d%d\n",&n,&m);
for (int i=1;i<=n;i++)
{
scanf("%s",s);
for (int j=1;j<=m;j++)
{
if ((s[j-1]=='.') || (s[j-1]=='S'))
{
a[i][j]=1;
if (s[j-1]=='S') stx=i,sty=j;
}
else
{
a[i][j]=0;
if (s[j-1]=='B') b[++cnt2]=(node){i,j,0};
if ((s[j-1]>='1') && (s[j-1]<='8'))
{
cnt1++;
g[s[j-1]-'0']=(node){i,j,0};
}
}
}
}
for (int i=1;i<=cnt1;i++) scanf("%d",&g[i].v);
}
void dp()
{
memset(f,0x3f3f3f3f,sizeof(f));
f[stx][sty][0]=0;
q.push((rec){stx,sty,0});
v[stx][sty][0]=1;
while (!q.empty())
{
rec u=q.front();
int x=u.x,y=u.y,s=u.s;
q.pop();
for (int i=0;i<4;i++)
{
int xx=x+dx[i],yy=y+dy[i];
if ((xx>0) && (yy>0) && (xx<=n) && (yy<=m))
{
if ((xx==1) && (yy==2))
int k=0;
if (a[xx][yy])
{
int sub=s;
if (i==1)
{
for (int j=1;j<=cnt1;j++)
{
if ((xx<g[j].x) && (yy==g[j].y)) sub^=1<<(j-1);
}
for (int j=1;j<=cnt2;j++)
{
if ((xx<b[j].x) && (yy==b[j].y)) sub^=1<<(cnt1+j-1);
}
}
if (i==3)
{
for (int j=1;j<=cnt1;j++)
{
if ((xx<g[j].x) && (yy+1==g[j].y)) sub^=1<<(j-1);
}
for (int j=1;j<=cnt2;j++)
{
if ((xx<b[j].x) && (yy+1==b[j].y)) sub^=1<<(cnt1+j-1);
}
}
if (f[xx][yy][sub]>f[x][y][s]+1)
{
f[xx][yy][sub]=f[x][y][s]+1;
if (!v[xx][yy][sub])
{
v[xx][yy][sub]=1;
q.push((rec){xx,yy,sub});
}
}
}
}
}
v[x][y][s]=0;
}
}
int calc(int x)
{
int sum=0,t=1<<(cnt1-1),k=cnt1;
while (x>0)
{
if (x>=t) sum+=g[k].v,x-=t;
t/=2;
k--;
}
return sum;
}
int main()
{
init();
dp();
int ans=0;
for (int i=0;i<(1<<cnt1);i++)
{
int d=calc(i);
ans=max(ans,d-f[stx][sty][i]);
}
printf("%d",ans);
}