题解:
首先发现假如一个豆豆被多边形围住了,那么从这个豆豆引出一条射线
会有奇数个焦点
然后我们从每个豆豆引出一条射线
然后状压dfs
代码:
#include<bits/stdc++.h> using namespace std; const int c[4][2]={{0,1},{0,-1},{1,0},{-1,0}}; struct point{int cx,cy,x,y;}b[15]; int n,m,d,ans,x,w[15],dis[12][12][520]; char mp[12][12]; struct node{int i,j,s;}; queue<node> q; int cross(int x,int y,int nx,int ny,int s) { for (int i=1;i<=d;i++) if (((x<b[i].cx&&nx>=b[i].cx)||(x>=b[i].cx&&nx<b[i].cx))&&y>b[i].cy)s^=1<<(i-1); return s; } void spfa(int sx,int sy) { q.push((node){sx,sy,0}); memset(dis,0x3f,sizeof(dis)); dis[sx][sy][0]=0; while (!q.empty()) { node x=q.front(); q.pop(); for (int k=0;k<4;k++) { int nx=x.i+c[k][0],ny=x.j+c[k][1]; if (nx<1||nx>n||ny<1||ny>m||mp[nx][ny]!=48) continue; int s=cross(x.i,x.j,nx,ny,x.s); if (dis[nx][ny][s]>dis[x.i][x.j][x.s]+1) { dis[nx][ny][s]=dis[x.i][x.j][x.s]+1; q.push((node){nx,ny,s}); } } } for (int i=0;i<1<<d;i++) { int res=-dis[sx][sy][i]; for (int j=1;j<=d;j++) if (i&(1<<(j-1))) res+=w[j]; ans=max(ans,res); } } int main() { scanf("%d%d%d",&n,&m,&d); for (int i=1;i<=d;i++) scanf("%d",&w[i]); for (int i=1;i<=n;i++) { scanf("%s",mp[i]+1); for (int j=1;j<=m;j++) if (mp[i][j]>48&&mp[i][j]<=57) { x=mp[i][j]-'0'; b[x]=(point){i,j,0,j+100}; } } for (int i=1;i<=n;i++) for (int j=1;j<=m;j++) if (mp[i][j]==48)spfa(i,j); printf("%d\n",ans); }