HDU-3502-Huson's Adventure Island(BFS+如压力DP)

简介:
Problem Description
A few days ago, Tom was tired of all the PC-games, so he went back to some old FC-games. "Hudson's Adventure Island" was his favorite which he had played thousands of times. But to his disappointed, the more he played, the more he lost. Tom soon gave up the game. 



Now, he invents an easier game on the base of “Hudson's Adventure Island”. He wants to know whether the new game is easy enough. So he came to you for help. 
To simplify the problem, you can assume there is matrix-map contains m(0 < m < 256) rows, n(0 < n < 256) columns, an entrance on the top-left corner (0, 0), an exit on the bottom-right corner (m-1, n-1). Each entry of the matrix contains a integer k.The range of k is defined below:
a)k = 0,it is a free space one can go through.
b)k = -1,it is an obstacle one can’t go through.
c)0 < k < 10000,it is a fruit one can go through and gain k points of energy.
d)k >= 0 at the entrance point and the end point.
At the begin, the hero has 0 points of energy and he can go four directions (up, down, left, right). Each move he makes cost 1 point of energy. No energy no move. If he can’t make a move or get to the exit, he loses the game. The number of fruit is 17 at most.
 

Input
The input consists of multiple test cases. Each test case starts with two positive integers m, n. Then follows m lines, each line contain n integers.
 

Output
For each case, if the hero can get the exit, find and print the maximum points of energy he left. Or print “you loss!”
 

Sample Input

  
  
4 4 8 0 0 0 -1 -1 -1 0 -1 -1 -1 0 0 6 0 0 3 3 4 0 0 0 0 0 0 0 0 4 4 5 0 0 0 0 -1 -1 0 0 -1 -1 0 0 0 0 0
 

Sample Output

  
  
4 0 you loss!
Hint
The hero can pass the exit. When he gets the exit point, he can choose to get out to finish the game or move on to gain more points of energy.
 

Author
imems
 

Source


思路:先用BFS 求出各个水果和终点之间的距离,再用状态压缩DP求解。


#include <cstdio>
#include <queue>
#define INF 999999999
#define max(A,B)(A>B?A:B)
using namespace std;

struct S{
int x,y;
}fruit[20],t;

int n,m,cnt,ans,mp[256][256],dis[20][20],cost[256][256],nxt[4][2]={{1,0},{0,1},{-1,0},{0,-1}},mx[1<<18][20],val[20];

void bfs(S t)
{
    int i,j,nx,ny;

    for(i=0;i<n;i++) for(j=0;j<m;j++) cost[i][j]=INF;

    queue<S>que;

    cost[t.x][t.y]=0;

    que.push(t);

    while(!que.empty())
    {
        t=que.front();

        for(i=0;i<4;i++)
        {
            nx=t.x+nxt[i][0];
            ny=t.y+nxt[i][1];

            if(nx>=0 && nx<n && ny>=0 && ny<m && mp[nx][ny]!=-1 && cost[nx][ny]==INF)
            {
                cost[nx][ny]=cost[t.x][t.y]+1;

                t.x=nx;
                t.y=ny;

                que.push(t);
            }

            t=que.front();
        }

        que.pop();
    }
}

int main()
{
    int i,j;

    while(~scanf("%d%d",&n,&m))
    {
        cnt=0;

        for(i=0;i<n;i++)
        {
            for(j=0;j<m;j++)
            {
                scanf("%d",&mp[i][j]);

                if(mp[i][j]>0)
                {
                    fruit[cnt].x=i;
                    fruit[cnt].y=j;

                    val[cnt++]=mp[i][j];
                }
            }
        }

        if(n==1 && m==1)
        {
            if(mp[0][0]>=0) printf("%d\n",mp[0][0]);
            else printf("you loss!\n");

            continue;
        }

        if(mp[0][0]<=0)
        {
            printf("you loss!\n");

            continue;
        }

        if(mp[n-1][m-1]==-1)
        {
            printf("you loss!\n");

            continue;
        }


        fruit[cnt].x=n-1;//终点也放进去
        fruit[cnt].y=m-1;


        for(i=0;i<=cnt;i++)
        {
            bfs(fruit[i]);

            for(j=0;j<=cnt;j++) dis[i][j]=cost[fruit[j].x][fruit[j].y];//各个水果和终点之间的距离

        }


        queue<S>que;

        for(i=1;i<(1<<cnt);i++) for(j=0;j<cnt;j++) mx[i][j]=-1;

        int v;

        t.x=1;
        t.y=0;

        mx[t.x][t.y]=val[0];

        que.push(t);

        while(!que.empty())
        {
            t=que.front();

            for(i=1;i<cnt;i++)
            {
                if(!(t.x & (1<<i)))
                {
                    v=mx[t.x][t.y]-dis[t.y][i];

                    if(v>=0)
                    {
                        t.x=(t.x | (1<<i));
                        t.y=i;

                        if(v+val[i]>mx[t.x][i])
                        {
                            mx[t.x][i]=v+val[i];
                            que.push(t);
                        }

                        t=que.front();
                    }
                }
            }

            que.pop();
        }

        ans=-1;

        for(i=1;i<(1<<cnt);i++) for(j=0;j<cnt;j++) ans=max(ans,mx[i][j]-dis[j][cnt]);

        if(ans>=0) printf("%d\n",ans);
        else puts("you loss!");
    }

}






本文转自mfrbuaa博客园博客,原文链接:http://www.cnblogs.com/mfrbuaa/p/5033639.html,如需转载请自行联系原作者


相关文章
|
8月前
|
Java
hdu-2544-最短路(SPFA)
hdu-2544-最短路(SPFA)
39 0
Light oj 1112 - Curious Robin Hood(树状数组)
有n个数,有m组操作,1 i表示将第i个数先输出,然后置0, 2 i v 表示给第i个数加上v, 3 i j 表示求i 到 j 的和,注意,这里数组是从0开始的,而我们构造的树状数组是从1 开始的,使用在程序中要进行一定的处理。
47 0
hdoj 1028/poj 2704 Pascal's Travels(记忆化搜索||dp)
有个小球,只能向右边或下边滚动,而且它下一步滚动的步数是它在当前点上的数字,如果是0表示进入一个死胡同。求它从左上角到右下角到路径数目。 注意, 题目给了提示了,要用64位的整数。
45 0
[Nowcoder] network | Tarjan 边双连通分量 | 缩点 | LCA倍增优化 | 并查集
题目描述 A network administrator manages a large network. The network consists of N computers and M links between pairs of computers. Any pair of computers are connected directly or indirectly by successive links, so data can be transformed between any two computers.
129 0
[Nowcoder] network | Tarjan 边双连通分量 | 缩点 | LCA倍增优化 | 并查集
All in the Family_upc_模拟 or lca + 并查集
The scientists working at the Family Genetics Institute are tracing the spread of a hereditary disease through family trees. They have started by listing the family members that have the disease,
128 0
All in the Family_upc_模拟 or lca + 并查集
HDU-3635,Dragon Balls(有点难度的并查集。。。)
HDU-3635,Dragon Balls(有点难度的并查集。。。)
|
机器学习/深度学习 算法
【刷穿 LeetCode】求「连通图经过所有点的最短路径」的三种方式 :「BFS」&「Floyd + 状压 DP」 &「AStar 算法」
【刷穿 LeetCode】求「连通图经过所有点的最短路径」的三种方式 :「BFS」&「Floyd + 状压 DP」 &「AStar 算法」
|
C语言
HDOJ/HDU Tempter of the Bone(深搜+奇偶性剪枝)
HDOJ/HDU Tempter of the Bone(深搜+奇偶性剪枝)
104 0
HDOJ/HDU 1372 Knight Moves(经典BFS)
HDOJ/HDU 1372 Knight Moves(经典BFS)
140 0
|
Java 数据安全/隐私保护
[LintCode] Number of Islands(岛屿个数)
描述 给一个01矩阵,求不同的岛屿的个数。 0代表海,1代表岛,如果两个1相邻,那么这两个1属于同一个岛。我们只考虑上下左右为相邻。 样例 在矩阵: [ [1, 1, 0, 0, 0], [0, 1, 0, 0, 1], [0, 0, 0, 1, 1], [0, 0, 0, 0, 0], [0, 0, 0, 0, 1] ] 中有 3 个岛。
1257 0

热门文章

最新文章