hdu 1044(bfs+状压)

非常经典的一类题型

没有多个出口。这里题目没有说清楚

Collect More Jewels

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)
Total Submission(s): 4684    Accepted Submission(s): 983

Problem Description

It is written in the Book of The Lady: After the Creation, the cruel god Moloch rebelled against the authority of Marduk the Creator.Moloch stole from Marduk the most powerful of all the artifacts of the gods, the Amulet of Yendor, and he hid it in the dark cavities of Gehennom, the Under World, where he now lurks, and bides his time.

Your goddess The Lady seeks to possess the Amulet, and with it to gain deserved ascendance over the other gods.

You, a newly trained Rambler, have been heralded from birth as the instrument of The Lady. You are destined to recover the Amulet for your deity, or die in the attempt. Your hour of destiny has come. For the sake of us all: Go bravely with The Lady!

If you have ever played the computer game NETHACK, you must be familiar with the quotes above. If you have never heard of it, do not worry. You will learn it (and love it) soon.

In this problem, you, the adventurer, are in a dangerous dungeon. You are informed that the dungeon is going to collapse. You must find the exit stairs within given time. However, you do not want to leave the dungeon empty handed. There are lots of rare jewels in the dungeon. Try collecting some of them before you leave. Some of the jewels are cheaper and some are more expensive. So you will try your best to maximize your collection, more importantly, leave the dungeon in time.

Input

Standard input will contain multiple test cases. The first line of the input is a single integer T (1 <= T <= 10) which is the number of test cases. T test cases follow, each preceded by a single blank line.

The first line of each test case contains four integers W (1 <= W <= 50), H (1 <= H <= 50), L (1 <= L <= 1,000,000) and M (1 <= M <= 10). The dungeon is a rectangle area W block wide and H block high. L is the time limit, by which you need to reach the exit. You can move to one of the adjacent blocks up, down, left and right in each time unit, as long as the target block is inside the dungeon and is not a wall. Time starts at 1 when the game begins. M is the number of jewels in the dungeon. Jewels will be collected once the adventurer is in that block. This does not cost extra time.

The next line contains M integers,which are the values of the jewels.

The next H lines will contain W characters each. They represent the dungeon map in the following notation:
> [*] marks a wall, into which you can not move;
> [.] marks an empty space, into which you can move;
> [@] marks the initial position of the adventurer;
> [<] marks the exit stairs;
> [A] - [J] marks the jewels.

Output

Results should be directed to standard output. Start each case with "Case #:" on a single line, where # is the case number starting from 1. Two consecutive cases should be separated by a single blank line. No blank line should be produced after the last test case.

If the adventurer can make it to the exit stairs in the time limit, print the sentence "The best score is S.", where S is the maximum value of the jewels he can collect along the way; otherwise print the word "Impossible" on a single line.

Sample Input

3

4 4 2 2
100 200
****
*@A*
*B<*
****

4 4 1 2
100 200
****
*@A*
*B<*
****

12 5 13 2
100 200
************
*B.........*
*.********.*
*@...A....<*
************

Sample Output

Case 1:
The best score is 200.

Case 2:
Impossible

Case 3:
The best score is 300.

Source

Asia 2005, Hangzhou (Mainland China), Preliminary

Recommend

JGShining   |   We have carefully selected several similar problems for you:  1195 1401 1067 1226 1104

#include <iostream>
#include <stdio.h>
#include <string.h>
#include <math.h>
#include <algorithm>
#include <string>
#include <queue>
#include <stdlib.h>
using namespace std;

struct node
{
    int x,y,cnt;
}que[2555];

int n,m,t,tj;
int cost[11];
int dis[25][25];
char g[55][55];
int sid,tid;
int mlink[55][55];
int qf,qd;
int up[4]={1,0,-1,0};
int rl[4]={0,1,0,-1};
int dp[12][12][10100];

void bfs(int sx,int sy)
{
    int mark[55][55];
    memset(mark,0,sizeof(mark));
    qf=qd=0;
    node finode;
    mark[sx][sy]=1;
    finode.x=sx; finode.y=sy; finode.cnt=0;
    que[qf++]=finode;
    while(qf>qd)
    {
        node cur=que[qd++];
        for(int i=0;i<4;i++)
        {
            int tx,ty;
            tx=cur.x+up[i];
            ty=cur.y+rl[i];
            if( (tx>=0&&tx<n)&&(ty>=0&&ty<m) && g[tx][ty]!=‘*‘&& mark[tx][ty]==0)
            {
                mark[tx][ty]=1;
                node nwnode;
                nwnode.cnt=cur.cnt+1;
                nwnode.x=tx;nwnode.y=ty;
                que[qf++]=nwnode;
                if(mlink[tx][ty]!=-1)
                {
                    dis[ mlink[tx][ty] ][ mlink[sx][sy] ]=nwnode.cnt;
                    dis[ mlink[sx][sy] ][ mlink[tx][ty] ]=nwnode.cnt;
                }
            }
        }
    }
}

int main()
{
    int T;
    int tt=1;
    scanf("%d",&T);
    int flag=0;
    while(T--)
    {
        if(flag) printf("\n");
        flag=1;
        scanf("%d%d%d%d",&m,&n,&t,&tj);
        for(int i=0;i<tj;i++)
            scanf("%d",cost+i);
        for(int i=0;i<n;i++)
        {
            scanf("%s",g[i]);
        }
        memset(dis,-1,sizeof(dis));
        memset(mlink,-1,sizeof(mlink));
        int id=0;
        for(int i=0;i<n;i++)
            for(int j=0;j<m;j++)
            {
                if(g[i][j]!=‘.‘&&g[i][j]!=‘*‘)
                {
                    if(g[i][j]==‘@‘)
                        mlink[i][j]=0;
                    else if( g[i][j]==‘<‘)
                    {
                        id++;
                        mlink[i][j]=tj+1;
                    }
                    else mlink[i][j]=g[i][j]-‘A‘+1;
                }
            }
        if(id>=2)
        {
            for(int i=0;i<100;i++)
                printf("%d\n",cost[i]);

        }
        for(int i=0;i<n;i++)
            for(int j=0;j<m;j++)
                if(g[i][j]!=‘.‘&&g[i][j]!=‘<‘&&g[i][j]!=‘*‘)
                {
                    bfs(i,j);
                }
        ////////////
        memset(dp,-1,sizeof(dp));
        dp[0][0][1]=0;

        for(int i=1;i<=tj;i++)
        {
            for(int j=0;j<=tj;j++)
            {
                for(int k=0; k<(1<<(tj+1)) ;k++)
                {
                    if(dp[i-1][j][k]!=-1 && dp[i-1][j][k] < t )
                    {
                        for(int p=1;p<=tj;p++)
                        {
                            if( (k&(1<<p)) ==0 &&dis[j][p]!=-1)
                            {
                                if(dp[i][p][(k|(1<<p))]==-1) dp[i][p][k|(1<<p)] = dp[i-1][j][k]+dis[j][p];
                                else dp[i][p][(k|(1<<p))] = min(dp[i][p][(k|(1<<p))],dp[i-1][j][k]+dis[j][p]);
                            }
                        }
                    }
                }
            }
        }
        int ans=-1;
        for(int i=0;i<=tj;i++)
            for(int j=0;j<=tj;j++)
                for(int k=0;k<(1<<(tj+1));k++)
                    if(dp[i][j][k]!=-1&&dis[j][tj+1]!=-1)
                        if(dp[i][j][k]+dis[j][tj+1]<=t)
                        {
                            int tmp=0;
                            for(int p=1;p<=tj;p++)
                                if( ((1<<p)&k)!=0 )
                                    tmp+=cost[p-1];
                            ans=max(ans,tmp);
                        }

        printf("Case %d:\n",tt++);
        if(ans==-1) printf("Impossible\n");
        else printf("The best score is %d.\n",ans);
    }
    return 0;
}

时间: 2024-08-23 02:30:43

hdu 1044(bfs+状压)的相关文章

hdu 2209 bfs+状压

http://acm.hdu.edu.cn/showproblem.php?pid=2209 不知为啥有种直觉,会出状压+搜索的题,刷几道先 简单的BFS,状压表示牌的状态, //#pragma comment(linker, "/STACK:102400000,102400000") #include <cstdio> #include <cstring> #include <algorithm> #include <string> #

HDU 5025 BFS+状压

2014 ACM/ICPC Asia Regional Guangzhou Online N*N矩阵 M个钥匙 K起点,T终点,S点需多花费1点且只需要一次,1-9表示9把钥匙,只有当前有I号钥匙才能拿I+1号钥匙,可以不拿钥匙只从上面走过 4维数组判重,第三维表示钥匙已经拿到第几把,第四维表示已经走过的S的状况,用状压存储 #include "stdio.h" #include "string.h" #include "queue" using

hdu 1429 bfs+状压

题意:这次魔王汲取了上次的教训,把Ignatius关在一个n*m的地牢里,并在地牢的某些地方安装了带锁的门,钥匙藏在地牢另外的某些地方.刚开始 Ignatius被关在(sx,sy)的位置,离开地牢的门在(ex,ey)的位置.Ignatius每分钟只能从一个坐标走到相邻四个坐标中的其中一 个.魔王每t分钟回地牢视察一次,若发现Ignatius不在原位置便把他拎回去.经过若干次的尝试,Ignatius已画出整个地牢的地图.现在请你帮 他计算能否再次成功逃亡.只要在魔王下次视察之前走到出口就算离开地牢

HDU 5040 BFS+状压

2014 ACM/ICPC Asia Regional Beijing Online 对于N*N的矩阵 M起点,T终点 有起始方向分别向北N,东E,南S,西W的摄像头,可以检测的范围为自己+所指方向1格,每1秒顺时针旋转90° 前面有灯或者自己站的地方有灯,移动需要花3秒,或者原地等一秒. BFS优先队列 开3维 hash数组判重,第三维是在该点等待的时间,开到4即可(摄像头转一圈) 对图中的每个点提前处理处会在什么时候被摄像头看到,用2进制压缩存储在MAP数组中 然后常规BFS解决 比赛时候手

HDU 3681 BFS&amp;状压DP&amp;二分

N*M矩阵,从F点出发,走完所有的Y点,每走一格花费1点电量,走到G点时,电量充满,D不可到达,问起始时的最小满电量可以走完所有Y,Y和G一共最多15个 先BFS出所有的F,Y,G之间的最短距离. 然后二分起始电量,对每个电量,做状压DP判断是否可行 #include "stdio.h" #include "string.h" #include "queue" using namespace std; int inf=0x3f3f3f3f; in

HDU 4771 BFS + 状压

Stealing Harry Potter's Precious Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 1343    Accepted Submission(s): 642 Problem Description Harry Potter has some precious. For example, his invisib

HDU 4771 BFS&amp;状压 水

n*m矩阵,起点@,从矩阵中拿k个物品的最小代价 水BFS #include "stdio.h" #include "string.h" #include "queue" using namespace std; int b[]={1,2,4,8,16}; int dir[4][2]={{1,0},{-1,0},{0,1},{0,-1}}; struct node { int x,y,step,status; }; int n,m,aim,s_x

hdu 4568 bfs + 状压dp

//这题的数据是不是有问题... 不考虑宝藏一个也拿不到也能AC... 1 #include "bits/stdc++.h" 2 using namespace std; 3 const int INF = 0x3f3f3f3f; 4 int T; 5 int N, M; 6 int mat[210][210]; 7 int K; 8 int tot_tra, tra[210][210]; 9 10 //dp parameters 11 int dis_tra_broder[20],

hdu 4771 Stealing Harry Potter&#39;s Precious (BFS+状压)

题意: n*m的迷宫,有一些格能走(“.”),有一些格不能走(“#”).起始点为“@”. 有K个物体.(K<=4),每个物体都是放在“.”上. 问最少花多少步可以取完所有物体. 思路: BFS+状压,看代码. 代码: struct node{ int x,s; node(int _x,int _s){ x=_x, s=_s; } }; int n,m,k,sx,sy; char graph[105][105]; int px[5],py[5]; int dp[105][105][35]; int