想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”。即使是规定了进出只能一次,那这个数据又该输出什么?

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

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

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

以上为个人YY

以下为题解:

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

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

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

#include<cstdio>
#include<iostream>
#include<algorithm>
#include<queue>
#include<cstring>
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<n&&y>=0&&y<m&&map[x][y]!=-1;
}
void bfs(int k)
{
priority_queue<node2> 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<n;i++)
for(int j=0;j<m;j++)
scanf("%d",&map[i][j]);
scanf("%d",&tre);
for(int i=1;i<=tre;i++)
{
scanf("%d%d",&t[i].x,&t[i].y);
ID[t[i].x][t[i].y]=i;
}
for(int i=1;i<=tre;i++)
{
bfs(i);
}
dis[0][0]=0;
if(!tre) {printf("0");continue;} for(int i=0;i<=tre;i++)
{
dp[1<<i][i]=dis[0][i];
}
int end=(1<<(tre+1));
for(int i=0;i<end;i++)
{
for(int j=0;j<=tre;j++)
{
if((i>>j)&1)
{
for(int k=0;k<=tre;k++)
{
if((i>>k)&1)
{
dp[i][j]=min(dp[i][j],dp[i&(~(1<<j))][k]+dis[k][j]);
}
}
}
}
}
printf("%d\n",dp[end-1][0]);
}
return 0;
}

hdu 4568 Hunter bfs建图+TSP状压DP的更多相关文章

  1. HDU 3247 Resource Archiver(AC自动机 + 状压DP + bfs预处理)题解

    题意:目标串n( <= 10)个,病毒串m( < 1000)个,问包含所有目标串无病毒串的最小长度 思路:貌似是个简单的状压DP + AC自动机,但是发现dp[1 << n][ ...

  2. HDU 3920Clear All of Them I(状压DP)

    HDU 3920   Clear All of Them I 题目是说有2n个敌人,现在可以发n枚炮弹,每枚炮弹可以(可以且仅可以)打两个敌人,每一枚炮弹的花费等于它所行进的距离,现在要消灭所有的敌人 ...

  3. HDU 5067 Harry And Dig Machine(状压dp)

    HDU 5067 Harry And Dig Machine 思路:因为点才10个,在加上一个起点,处理出每一个点之间的曼哈顿距离,然后用状压dp搞,状态表示为: dp[i][s],表示在i位置.走过 ...

  4. HDU - 6125: Free from square (状压DP+分组背包)

    problem:给定N,K.表示你有数1到N,让你最多选择K个数,问有多少种方案,使得选择的数的乘积无平方因子数.N,K<500: solution:显然可以状压DP做,但是500以内的素数还是 ...

  5. HDU 6984 - Tree Planting(数据分治+状压 dp)

    题面传送门 傻逼卡常屑题/bs/bs,大概现场过得人比较少的原因就是它比较卡常罢(Fog 首先对于这样的题我们很难直接维护,不过注意到这个 \(n=300\) 给得很灵性,\(k\) 比较小和 \(k ...

  6. hdu 6086 -- Rikka with String(AC自动机 + 状压DP)

    题目链接 Problem Description As we know, Rikka is poor at math. Yuta is worrying about this situation, s ...

  7. HDU 2825 Wireless Password(AC自动机 + 状压DP)题解

    题意:m个密码串,问你长度为n的至少含有k个不同密码串的密码有几个 思路:状压一下,在build的时候处理fail的时候要用 | 把所有的后缀都加上. 代码: #include<cmath> ...

  8. HDU - 3247 Resource Archiver (AC自动机,状压dp)

    \(\quad\)Great! Your new software is almost finished! The only thing left to do is archiving all you ...

  9. HDU - 6321 Problem C. Dynamic Graph Matching (状压dp)

    题意:给定一个N个点的零图,M次操作,添加或删除一条边,每一次操作以后,打印用1,2,...N/2条边构成的匹配数. 分析:因为N的范围很小,所以可以把点的枚举状态用二进制表示集合.用一维数组dp[S ...

随机推荐

  1. Codeforces 1082 D. Maximum Diameter Graph-树的直径-最长链-构造题 (Educational Codeforces Round 55 (Rated for Div. 2))

    D. Maximum Diameter Graph time limit per test 2 seconds memory limit per test 256 megabytes input st ...

  2. SSM整合所需jar包

    MySql驱动包 mysql-connector-java-5.1.7-bin.jar MyBatis的核心包和依赖包 mybatis-3.2.7.jar(核心包)asm-3.3.1.jar(依赖包) ...

  3. Flask实战第38天:前台模型创建

    安装shortuuid pip install shortuuid 编辑front.models.py from exts import db import shortuuid from werkze ...

  4. 【BZOJ 1455】 1455: 罗马游戏 (可并堆-左偏树+并查集)

    1455: 罗马游戏 Description 罗马皇帝很喜欢玩杀人游戏. 他的军队里面有n个人,每个人都是一个独立的团.最近举行了一次平面几何测试,每个人都得到了一个分数. 皇帝很喜欢平面几何,他对那 ...

  5. 如何上传word

    韩梦飞沙  韩亚飞  313134555@qq.com  yue31313  han_meng_fei_sha word图片上传控件 word 图片 上传

  6. [ARC 066] Tutorial

    Link: ARC 066 传送门 C: 如果存在可行方案则答案为$2^{n/2}$ #include <bits/stdc++.h> using namespace std; #defi ...

  7. 洛谷 P3943 星空

    题目背景 命运偷走如果只留下结果, 时间偷走初衷只留下了苦衷. 你来过,然后你走后,只留下星空. 题目描述 逃不掉的那一天还是来了,小 F 看着夜空发呆. 天上空荡荡的,没有一颗星星——大概是因为天上 ...

  8. [CODE FESTIVAL 2017]Poor Penguin

    题意:在一个$n\times m$的网格上,每个格子是薄冰或冰山(网格外什么都没有),有一片薄冰上站着一只企鹅,对于薄冰$(i,j)$,如果不满足($(i-1,j),(i+1,j)$都有东西或$(i, ...

  9. 【推导】【模拟】AtCoder Regular Contest 082 F - Sandglass

    题意:有个沙漏,一开始bulb A在上,bulb B在下,A内有a数量的沙子,每一秒会向下掉落1.然后在K个时间点ri,会将沙漏倒置.然后又有m个询问,每次给a一个赋值ai,然后询问你在ti时刻,bu ...

  10. 【博弈论】【SG函数】【线段树】Petrozavodsk Summer Training Camp 2016 Day 9: AtCoder Japanese Problems Selection, Thursday, September 1, 2016 Problem H. Cups and Beans

    一开始有n个杯子,每个杯子里有一些豆子,两个人轮流操作,每次只能将一个豆子移动到其所在杯子之前的某个杯子里,不过可以移动到的范围只有一段区间.问你是否先手必胜. 一个杯子里的豆子全都等价的,因为sg函 ...