添加链接描述
因为怪物数量小于等于10 所以可以枚举每个怪物是否选择通过 使用状压枚举的方式从当前位开始bfs 选择dist最小的可能性
#include<bits/stdc++.h>
using namespace std;
const int N=60;
char arr[N][N];
struct node {
int x,y,h;
};
vector<node >b;
typedef pair<int,int> pii;
int vis[N][N],dist[N][N];
int dx[]={0,0,1,-1};
int dy[]={1,-1,0,0};
int n,m,h;
int res=0x3f3f3f3f;
int mp[N][N];
void bfs(){
queue<pii>q;
memset(vis,0,sizeof vis);
memset(dist,0x3f3f3f3f,sizeof dist);
q.push({0,0});
vis[0][0]=1;
dist[0][0]=0;
while(q.size()){
pii p=q.front();
q.pop();
for(int i=0;i<4;i++){
int x=p.first+dx[i],y=p.second+dy[i];
if(x>=0&&x<n&&y>=0&&y<m&&vis[x][y]==0){
if(arr[x][y]=='.'||(arr[x][y]!='*'&&mp[x][y])){
//!!如果当前为通行 或者不为通信但是mp被选中
vis[x][y]=1;
q.push({x,y});
dist[x][y]=dist[p.first][p.second]+1;
}
}}
}
//cout<<dist[n-1][m-1]<<endl;
res=min(res,dist[n-1][m-1]);
}
int main(){
cin>>n>>m>>h;
for(int i=0;i<n;i++)scanf("%s",arr[i]);
for(int i=0;i<n;i++){
for(int j=0;j<m;j++){
if(arr[i][j]>='0'&&arr[i][j]<='9')b.push_back({i,j,arr[i][j]-'0'});
}
}
for(int i=0;i<1<<b.size();i++){
int sum=0;
for(int j=0;j<b.size();j++){
if((i>>j)&1)mp[b[j].x][b[j].y]=1,sum+=b[j].h;//!!
//状压枚举 i右移枚举当前这位
else mp[b[j].x][b[j].y]=0;
}
// cout<<sum<<endl;
if(sum>=h)continue;
bfs();
}
if(res==0x3f3f3f3f)cout<<"-1"<<endl;
else
cout<<res<<endl;
return 0;
}