【SCOI2009】围豆豆

题面

https://www.luogu.org/problem/P2566

题解

// luogu-judger-enable-o2
#include<cstdio>
#include<iostream>
#include<cstring>
#include<queue>
#define N 15
#define ri register int
using namespace std;
const int dx[]={1,-1,0,0},dy[]={0,0,1,-1};
char g[N][N];
int n,m,d,ans,v[N];
int f[N][N][1<<9],sum[1<<9];
bool vis[N][N][1<<9];
struct node {int x,y,s;};
int x[N],y[N];

int get(int fx,int fy,int nx,int ny,int s){
  for (ri i=0;i<d;i++)
    if (((fx==x[i] && nx>x[i])||(fx>x[i] && nx<=x[i]))&&ny>y[i]) s^=(1<<i);
  return s;
}

void spfa(int x,int y) {
  queue<node> q; memset(f,0x3f,sizeof(f));
  f[x][y][0]=0; q.push((node){x,y,0});
  while (!q.empty()) {
    node cur=q.front(); q.pop();
    int x=cur.x,y=cur.y,s=cur.s;
    for (ri i=0;i<4;i++) {
      int nx=x+dx[i],ny=y+dy[i];
      if (g[nx][ny]!='0') continue;
      int ns=i<2?get(x,y,nx,ny,s):s;
      if (f[nx][ny][ns]>f[x][y][s]+1) {
        f[nx][ny][ns]=f[x][y][s]+1;
        if (!vis[nx][ny][ns]) vis[nx][ny][ns]=1,q.push((node){nx,ny,ns});
      }
    }
    vis[x][y][s]=0;
  }
  for (ri i=0;i<1<<d;i++) ans=max(ans,sum[i]-f[x][y][i]);
}

int main(){
  scanf("%d%d%d",&n,&m,&d);
  for (ri i=0;i<d;i++) scanf("%d",&v[i]);
  memset(g,'#',sizeof(g));
  for (ri i=1;i<=n;i++) scanf("%s",g[i]+1),g[i][m+1]='#';
  for (ri i=1;i<=n;i++) 
    for (ri j=1;j<=m;j++) if (g[i][j]>='1' && g[i][j]<='9') x[g[i][j]-'1']=i,y[g[i][j]-'1']=j;
  for (ri i=0;i<1<<d;i++)
    for (ri j=0;j<d;j++) if (i&(1<<j)) sum[i]+=v[j];
  ans=-1e9;
  for (ri i=1;i<=n;i++)
    for (ri j=1;j<=m;j++) if (g[i][j]=='0') spfa(i,j);
  cout<<ans<<endl;
}
posted @ 2019-07-31 19:05  HellPix  阅读(154)  评论(0编辑  收藏  举报