设为首页 加入收藏

TOP

hdu 4568 Hunter bfs建图+TSP状压DP
2014-11-23 17:44:38 来源: 作者: 【 】 浏览:2
Tags:hdu 4568 Hunter bfs 建图 TSP 状压

想AC的人请跳过这一段。。。

题目应该都能读懂。但是个人觉得这题出的很烂,意思太模糊了。

首先,进出次数只能是一次!!这个居然在题目中没有明确说明,让我在当时看到题目的时候无从下手。

因为我想到了这几个数据:

1 1 1 1 9 1 -1 -1 -1

-1-1-1 9 9 9 -1 1 -1

1 1 1 1 9 1 -1 -1 -1

6个宝藏 四个角是宝藏 中间是宝藏

第一个数据如果进出2次,就可以拿走全部的6个宝藏,也符合题目的“bring out all treasures he can take”。

即使是规定了进出只能一次,那这个数据又该输出什么?( if nothing James can get, please output 0)

第二个数据如果进出4次,就可以最快的拿走全部宝藏。

第三个数据唯一的宝藏拿不走。

不过,这题的测试数据中并没有上面的例子。

以上为个人YY


以下为题解:

进出一次,找到所有能找到的宝藏,裸的TSP问题。

首先选一个自己喜欢的算法建图。将整个边界理解成一个点,找到每两个宝藏之间的最短距离和每个宝藏的离边界点的最短距离。

然后就是TSP,状态压缩DP解。


#include
#include
#include
#include
#include
using namespace std;
int n,m,tre;
int ID[205][205];
int map[205][205];
int dis[20][20];
bool vis[205][205];
int dp[1<<16][20];
struct node
{
    int x,y;
}t[20];
struct node2
{
    int x,y,dis;
    bool operator <(const node2 & f) const
    {
        return dis>f.dis;
    }
};
int dx[]={-1,1,0,0};
int dy[]={0,0,-1,1};
bool isok(int x,int y)
{
    return x>=0&&x=0&&y Q;
    int v[20]={0};
    memset(vis,0,sizeof(vis));
    node2 f,r;
    r.x=t[k].x;
    r.y=t[k].y;
    r.dis=0;
    Q.push(r);
    v[k]=1;
    vis[r.x][r.y]=1;
    int tot=1,id;
    while(!Q.empty())
    {
        f=Q.top(); Q.pop();
        if(!v[0]&&(f.x==0||f.y==0||f.x==n-1||f.y==m-1))
        {
            v[0]=1;
            dis[k][0]=f.dis;
            dis[0][k]=f.dis+map[t[k].x][t[k].y];
            tot++;
            if(tot==tre+1) return;
        }
        id=ID[f.x][f.y];
        if(id&&!v[id])
        {
            tot++;
            v[id]=1;
            dis[k][id]=f.dis;
            if(tot==tre+1) return;
        }
        for(int d=0;d<4;d++)
        {
            r.x=f.x+dx[d];
            r.y=f.y+dy[d];
            r.dis=f.dis+map[r.x][r.y];
            if(isok(r.x,r.y)&&!vis[r.x][r.y])
            {
                vis[r.x][r.y]=1;
                Q.push(r);
            }
        }
    }
}
int main()
{
    int cas;
    scanf("%d",&cas);
    while(cas--)
    {
        memset(ID,0,sizeof(ID));
        memset(dis,0x3f,sizeof(dis));
        memset(dp,0x3f,sizeof(dp));
        scanf("%d%d",&n,&m);
        for(int i=0;i>j)&1)
                {
                    for(int k=0;k<=tre;k++)
                    {
                        if((i>>k)&1)
                        {
                            dp[i][j]=min(dp[i][j],dp[i&(~(1< 
 

】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
分享到: 
上一篇hdu 1005 下一篇UVA 270 Lining Up (几何 判断共..

评论

帐  号: 密码: (新用户注册)
验 证 码:
表  情:
内  容:

·请问c语言刚入门,该 (2025-12-26 10:21:04)
·python 编程怎么定义 (2025-12-26 10:21:01)
·09-指 针 (一)-c语言 (2025-12-26 10:20:58)
·About - Redis (2025-12-26 08:20:56)
·Redis: A Comprehens (2025-12-26 08:20:53)