hdu-1044(bfs+压位/dfs)

题意:给出起点终点,还有若干宝藏,问你能否走出迷宫,并尽可能带走价值最多的宝藏。

题解:最多有十个宝藏我们可以开一个三位数组vis[i][x][y]表示在x,y点已经拥有i状态的宝藏的。i有二进制压缩当前状态拥有的宝藏。

#include <iostream>
#include <string.h>
#include <algorithm>
#include <stdio.h>
#include <queue>
using namespace std;
struct node{
	int bit;
	int x,y,step;
};
const int maxn=55;  
bool vis[1100][maxn][maxn];
int n,m,l,ge;
char s[maxn][maxn];
int sx,sy,ex,ey;
int weigth[11];

int Sum(int bit)
{
	int sum=0;
	for(int i=0;i<ge;i++)
	{
		if((1<<i)&bit)sum+=weigth[i];
	}
	return sum;
}
int csa=0;
int dx[4]={0,0,1,-1};
int dy[4]={1,-1,0,0};
int bfs()
{
    memset(vis,0,sizeof(vis));  
	csa++;
	queue<node> q;
	node now;now.x=sx,now.y=sy;now.step=0;now.bit=0;
	q.push(now);vis[0][sx][sy]=1;int ans=0;
	while(!q.empty())
	{
		node u=q.front();q.pop();
		//printf("%d %d\n",u.x,u.y);
		for(int i=0;i<4;i++)
		{
			int x=u.x,y=u.y,step=u.step,bit=u.bit;
			int x1=x+dx[i];int y1=y+dy[i];
			if(x1>=1&&x1<=n&&y1>=1&&y1<=m&&s[x1][y1]!='*')
			{
				node v;v.x=x1;v.y=y1;v.step=step+1;
				if(s[x1][y1]>='A'&&s[x1][y1]<='Z')
				v.bit=(bit|(1<<(s[x1][y1]-'A')));
				else v.bit=bit;
				if(vis[v.bit][v.x][v.y]==1) continue;
				else vis[v.bit][v.x][v.y]=1;  
				if(s[x1][y1]=='<') ans=max(ans,Sum(v.bit));
				if(v.step==l) continue;
				q.push(v);

			}
		}
	}
	
	printf("Case %d:\n",csa);
	if(ans==0) printf("Impossible\n");
	else printf("The best score is %d.\n",ans);
}
int main()
{
	int t;scanf("%d",&t);
	while(t--)
	{
		scanf("%d%d%d%d",&m,&n,&l,&ge);
		for(int i=0;i<ge;i++) scanf("%d",&weigth[i]);
		for(int i=1;i<=n;i++)scanf("%s",s[i]+1);
		
		for(int i=1;i<=n;i++)
		{
			for(int j=1;j<=m;j++)
			{
				if(s[i][j]=='<')
				{
					ex=i;ey=j;
				}
				if(s[i][j]=='@')
				{
					sx=i;sy=j;s[i][j]='.';
				}
			}
		}
		bfs();
		if(t!=0)
		printf("\n");
	}
	return 0;
}

另一种方法是bfs搜索任意两点最短距离,dfs搜索答案。



猜你喜欢

转载自blog.csdn.net/qq_37632935/article/details/80101041
今日推荐