hdu 1044(bfs+dfs+剪枝)

Collect More Jewels

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

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.

TLE 无数发,QAQ,能够想到的剪枝都想了,终于AC..

题意:某人要从‘@‘走到‘<‘ ,途中经过一些有宝石的点,这些点的宝石分别有自己的价值,‘A‘对应的是第一个宝石...依次类推,最多10个,现在某人要保证能够走到终点的同时尽量多收集宝石,问他最多能够收集多少宝石,不能走到终点输出Impossible.

题解:对每个点进行bfs,求出其到每个点的距离,接下来就做一次DFS即可得到答案,这题坑点在DFS时候的剪枝,当答案已经为sum(jewel[i])时就不用继续搜索了,不然的话会将全排列都搜索一遍,会超时。

#include <iostream>
#include <algorithm>
#include <stdio.h>
#include <string.h>
#include <queue>
using namespace std;
const int INF = 999999999;
int n,m,limit,num;
int dis[60][60]; ///记录两点之间的距离
int jw[60];
struct Node{
    int x,y,step,geshu;
}s;
char graph[60][60];
bool vis[60][60];
int dir[][2]={{1,0},{-1,0},{0,1},{0,-1}};
bool check(int x,int y){
    if(x<1||x>n||y<1||y>m||vis[x][y]||graph[x][y]==‘*‘) return false;
    return true;
}
void bfs(Node s,int k){
    queue<Node> q;
    vis[s.x][s.y] = true;
    s.geshu = 1;
    q.push(s);
    while(!q.empty()){
        Node now = q.front();
        q.pop();
        if(now.geshu==num+2) return;
        for(int i=0;i<4;i++){
            Node next;
            next.x = now.x+dir[i][0];
            next.y = now.y+dir[i][1];
            if(!check(next.x,next.y)) continue;
            char c = graph[next.x][next.y];
            next.step = now.step+1;
            next.geshu = now.geshu+1;
            if(c==‘.‘) next.geshu-=1;
            if(c==‘@‘){
                dis[k][0] = next.step;
            }
            else if(c>=‘A‘&&c<=‘J‘) {
                dis[k][c-‘A‘+1] = next.step;
            }else if(c==‘<‘){
                dis[k][num+1] = next.step;
            }
            vis[next.x][next.y] = true;
            q.push(next);
        }
    }
}
bool vis1[60];
int MAX = 0,sum;
void dfs(int u,int step,int ans){
    if(step>limit || MAX == sum) return ; ///必须要加剪枝
    if(u==num+1){
        MAX = max(MAX,ans);
        return;
    }
    for(int i=0;i<=num+1;i++){
        if(!vis1[i]){
            vis1[i] = true;
            dfs(i,step+dis[u][i],ans+jw[i]);
            vis1[i] = false;
        }
    }
}
int main(){
    int tcase;
    scanf("%d",&tcase);
    int  kk = 1;
    while(tcase--){
        for(int i=0;i<30;i++){
            for(int j=0;j<30;j++){
                dis[i][j] = (i==j)?0:INF;
            }
        }
        scanf("%d%d%d%d",&m,&n,&limit,&num);
        sum = 0;
        for(int i=1;i<=num;i++){
            scanf("%d",&jw[i]);
            sum+=jw[i];
        }
        jw[num+1] = jw[0] = 0;
        for(int i=1;i<=n;i++){
            scanf("%s",graph[i]+1);
        }
        for(int i=1;i<=n;i++){
            for(int j=1;j<=m;j++){
                if(graph[i][j]==‘@‘) {
                    memset(vis,false,sizeof(vis));
                    s.x = i,s.y = j,s.step=0;
                    bfs(s,0);
                }
                if(graph[i][j]==‘<‘){
                    memset(vis,false,sizeof(vis));
                    s.x = i,s.y = j,s.step=0;
                    bfs(s,num+1);
                }
                if(graph[i][j]>=‘A‘&&graph[i][j]<=‘J‘){
                    memset(vis,false,sizeof(vis));
                    s.x = i,s.y = j,s.step=0;
                    bfs(s,graph[i][j]-‘A‘+1);
                }
            }
        }
        printf("Case %d:\n",kk++);
        if(dis[0][num+1]>limit){
            printf("Impossible\n");
            if(tcase) printf("\n");
            continue;
        }
        memset(vis1,false,sizeof(vis1));
        MAX = 0;
        vis1[0] = true;
        dfs(0,0,0);
        printf("The best score is %d.\n",MAX);
        if(tcase) printf("\n");
    }
}
时间: 2024-07-28 17:15:44

hdu 1044(bfs+dfs+剪枝)的相关文章

hdu 1044 bfs+dfs

//方便以后回顾错误//http://acm.hdu.edu.cn/showproblem.php?pid=1044//题意 给定起点.终点和图上的宝藏的权值,问 在规定的步数内能否从起点走到终点:若能走到,可携带宝藏的总价值最大是多少 1 #include<cstdio> 2 #include<cstring> 3 #include<iostream> 4 #include<queue> 5 #include<vector> 6 using n

hdu 1983(BFS+DFS) 怪盗Kid

http://acm.hdu.edu.cn/showproblem.php?pid=1983 首先,题目要求出口和入口不能封闭,那么,只要把出口或入口的周围全给封闭了那盗贼肯定无法成功偷盗,出口或入口周围最多 会有四个点,所以初始答案ans=4(没必要计算出出口或入口可以封闭的最小值,就初始为4就好),然后从一到四枚举看有没有 最小的符合条件的值, 所以先用BFS查找出至少偷到一个宝石的最小时间的路径,记录下来,然后枚举封闭路径上的点递归回去,再BFS判断是否能偷盗 成功---DFS中插入BFS

hdu - 1072(dfs剪枝)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1072 思路:深搜每一个节点,并且进行剪枝,记录每一步上一次的s1,s2:如果之前走过的时间小于这一次, 就说明有更短的:路径,所以就不用继续遍历下去. #include<iostream> #include<cstdio> #include<cstring> using namespace std; int a[20][20],step[20][20],tim[20][20

HDU 1983 BFS&amp;&amp;DFS

最多只需要封锁4个区域即可,DFS封锁的区域,BFS是否可通过 #include "stdio.h" #include "string.h" #include "queue" using namespace std; int dir[4][2]={{1,0},{-1,0},{0,1},{0,-1}}; int s_x,s_y,n,m,t; char str[11][11]; struct node { int x,y,step,key; }; i

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: Afte

HDU ACM 1044 Collect More Jewels BFS+DFS

题意:在一个迷宫中,有一些宝物,从起点走到终点,问在给定的时间内,到达终点后所能拾取珠宝的最大价值. 分析(BFS+DFS): 1.求入口到第一个取宝物的地方的最短距离 2.求第i个取宝物的地方到第i+1个取宝物的地方的最短距离 3.求第n个取宝物的地方到出口的最短距离 4.保证以上3点能在时间L内实现的情况下,取得的宝石价值最大. BFS特点:对于解决最短或最少问题特别有效,而且寻找深度小,但缺点是内存耗费量大(需要开大量的数组单元来存储状态) DFS特点:对于解决遍历和求所有问题有效,对于问

hdu 4109 dfs+剪枝优化

求最久时间即在无环有向图里求最远路径 dfs+剪枝优化 从0节点(自己增加的)出发,0到1~n个节点之间的距离为1,mt[i]表示从0点到第i个节点目前所得的最长路径 #include<iostream> #include<cstdio> #include<cstring> #include<string> #include<algorithm> #include<vector> using namespace std; const

HDU 1010 Tempter of the Bone dfs+剪枝

给你一个迷宫一个起点和一个终点,问你能否走T步刚好到达终点,不能重复走,并且只有4个方向 显然这是一个dfs,虽然N最大只有7,但是裸的dfs复杂度还是太高了,因此要进行一些剪枝 1.如果T比图上所有的可走点还要大,肯定是不可行的.这个可以避免dfs整张图. 2.奇偶剪枝,有性质当前点(x,y)到目标点(tx,ty)的所有路径的长度的奇偶性一定和|x-tx|+|y-ty|一样. #include <cstdio> #include <iostream> #include <c

hdu 4771 Stealing Harry Potter&#39;s Precious (2013亚洲区杭州现场赛)(搜索 bfs + dfs) 带权值的路径

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4771 题目意思:'@'  表示的是起点,'#' 表示的是障碍物不能通过,'.'  表示的是路能通过的: 目的:让你从 '@' 点出发,然后每个点只能走一次,求出最小的距离: 解题思路:先用 bfs 求解出任意两点之间的距离,用 ans[i][j],表示点 i 到点  j 的距离: 然后用 dfs 递归求出从起点经过所有点的距离中,比较出最小的: AC代码: 1 #include<iostream>