hdu(1044) Collect More Jewels

//本题要用到bfs和dfs两种搜索;
//用bfs的目的就是寻找最短路径(把点存在了队列中);
//寻找起点,终点,财宝,两两之间的距离,最后存在dp数组中;

//dfs作用就是搜索从起点到终点;
//在time允许的情况下,所能携带最多的财富;

 

 

#include"stdio.h"
#include"string.h"
#include"queue"
using namespace std;
char map[100][100];
int visit[100][100],a[100];
int step[100][100],mark[100];
int dp[100][100];
int w,h,l,m,maxx,sum;
int dir[4][2]={-1,0,  1,0,  0,1,  0,-1};
int judge(int x,int y)
{
 if(x>=0&&x<w&&y>=0&&y<h&&map[x][y]!='*')
  return 1;
 return 0;

void bfs(int x,int y,int n)
{
 int i;
 memset(visit,0,sizeof(visit));
 memset(step,0,sizeof(step));
 queue<int>q;
    int u=x*h+y;
 visit[x][y]=1;
 step[x][y]=0;
 q.push(u);
 while(!q.empty())
 {
  u=q.front();
  q.pop();
  x=u/h;
  y=u%h;
  for(i=0;i<4;i++)
  {
   int xx=x+dir[i][0];
   int yy=y+dir[i][1];
   step[xx][yy]=step[x][y]+1;
   if(judge(xx,yy)&&visit[xx][yy]==0)
   {
    if(map[xx][yy]=='@')
     dp[n][0]=step[xx][yy];
    else if(map[xx][yy]=='<')
     dp[n][m+1]=step[xx][yy];
    else if(map[xx][yy]>='A'&&map[xx][yy]<='J')
     dp[n][map[xx][yy]-'A'+1]=step[xx][yy];
    visit[xx][yy]=1;
    q.push(xx*h+yy);
   }
  }
 }
}
void dfs(int now,int v,int time) 

    if(time>l) 
        return ; 
    if(maxx==sum) 
        return ; 
    if(now>m) 
    { 
        if(v>maxx) 
            maxx=v; 
        return; 
    } 
    int i; 
    for(i=0;i<=m+1;i++) 
    { 
        if(dp[now][i]&&mark[i]==0) 
  {
        mark[i]=1; 
        dfs(i,v+a[i],time+dp[now][i]); 
        mark[i]=0; 
  }
    } 

int main()
{
 int i,j,k,r=1,t;
 scanf("%d",&k);
 for(t=1;t<=k;t++)
 {
  sum=0;
  memset(mark,0,sizeof(mark));
  memset(dp,0,sizeof(dp));
  scanf("%d%d%d%d",&h,&w,&l,&m);
  for(i=1;i<=m;i++)
  {
   scanf("%d",&a[i]);
   sum+=a[i];
  }
  a[0]=a[m+1]=0;
  for(i=0;i<w;i++)
   scanf("%s",map[i]);
  for(i=0;i<w;i++)
   for(j=0;j<h;j++)
   {
    if(map[i][j]=='@')
    {
     bfs(i,j,0);
    }
    else if(map[i][j]=='<')
    {
     bfs(i,j,m+1);
    }
    else if(map[i][j]>='A'&&map[i][j]<='J')
    {
     bfs(i,j,map[i][j]-'A'+1);
    }
   }
   mark[0]=1;maxx=-1;dfs(0,0,0);
   if(t!=1)
    printf("\n");
   printf("Case %d:\n",r++);
   if(maxx!=-1)
    printf("The best score is %d.\n",maxx);
   else
    printf("Impossible\n");
 }
 return 0;
}

 


 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值