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,如需转载请自行联系原作者


相关文章
|
XML 前端开发 JavaScript
ajax原理是什么?如何实现?
ajax原理是什么?如何实现?
269 0
|
JavaScript
DOM 节点列表长度(Node List Length)
`length`属性用于获取DOM节点列表的元素数量。通过遍历这个属性,如`for (i=0;i&lt;x.length;i++)`,可以访问和处理每个节点。在示例中,代码加载&quot;books.xml&quot;,然后获取所有&quot;title&quot;标签,并打印它们的子节点值。
|
JavaScript Java 测试技术
基于ssm+vue.js+uniapp小程序的驾校预约管理系统附带文章和源代码部署视频讲解等
基于ssm+vue.js+uniapp小程序的驾校预约管理系统附带文章和源代码部署视频讲解等
143 0
基于ssm+vue.js+uniapp小程序的驾校预约管理系统附带文章和源代码部署视频讲解等
|
安全 网络安全 C#
2022年8月的工作经历
2022年8月的工作经历
|
JavaScript Dubbo Java
我们公司使用了 6 年的Spring Boot 项目部署方案!打包 + Shell 脚本部署详解
我们公司使用了 6 年的Spring Boot 项目部署方案!打包 + Shell 脚本部署详解
我们公司使用了 6 年的Spring Boot 项目部署方案!打包 + Shell 脚本部署详解
|
分布式计算 Kubernetes Cloud Native
带你读《企业级云原生白皮书项目实战》——2.2 云原生的发展及现状(上)
带你读《企业级云原生白皮书项目实战》——2.2 云原生的发展及现状(上)
648 0
|
存储 程序员 编译器
STM32-内存五区
一个由C/C++编译的程序占用的内存分为以下几个部分 * 栈区(stack)— **由编译器自动分配释放,存放函数的参数值,局部变量的值等**。 * 堆区(heap) — **由程序员分配和释放,若程序员不释放,程序结束时可能由OS回收**。 * 全局区(静态区)(static)—**全局变量和静态变量的存储是放在一块的,初始化的全局变量和静态变量在一块区域,未初始化的全局变量、未初始化的静态变量在相邻的另一块区域**。 * 文字常量区 — **常量字符串就是放在这里的**。 * 程序代码区 — **存放函数体的二进制代码**。
249 0
STM32-内存五区
|
消息中间件 数据安全/隐私保护
它让你1小时精通RabbitMQ消息队列(新增死信处理)
它让你1小时精通RabbitMQ消息队列(新增死信处理)
429 0
它让你1小时精通RabbitMQ消息队列(新增死信处理)