题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4568

思路:首先spfa预处理出每对宝藏之间的最短距离以及宝藏到边界的最短距离,然后dp[state][u]表示当前在点u,状态为state的最短距离,然后更新就行。

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <queue>
using namespace std; const int MAX_N = (233);
const int inf = 0x3f3f3f3f;
int N, M, n, g[MAX_N][MAX_N]; struct Point {
int x, y;
} point[14]; int d[14][14], dd[14], dp[(1 << 14) + 4][14]; //d[i][j]表示宝藏i到宝藏j之间的最短距离,dd[i]表示宝藏i到边界的最短距离
bool vis[MAX_N][MAX_N]; struct Node {
int x, y, step;
Node () {}
Node (int _x, int _y, int _step) : x(_x), y(_y), step(_step) {}
}; int dist[MAX_N][MAX_N], dir[4][2] = {
{-1, 0}, {1, 0}, {0, -1}, {0, 1}
};
void spfa(int index)
{
for (int i = 0; i < N; ++i) {
for (int j = 0; j < M; ++j) dist[i][j] = inf, vis[i][j] = false;
}
queue<pair<int, int > > que;
que.push(make_pair(point[index].x, point[index].y));
dist[point[index].x][point[index].y] = 0; while (!que.empty()) {
pair<int, int > p = que.front();
que.pop(); vis[p.first][p.second] = false; for (int i = 0; i < 4; ++i) {
int x = p.first + dir[i][0];
int y = p.second + dir[i][1]; if (g[x][y] == -1) continue; if (x < 0 || x >= N || y < 0 || y >= M) {
dd[index] = min(dd[index], dist[p.first][p.second] + g[point[index].x][point[index].y]);
continue;
} if (dist[p.first][p.second] + g[x][y] < dist[x][y]) {
dist[x][y] = dist[p.first][p.second] + g[x][y];
if (!vis[x][y]) {
vis[x][y] = true;
que.push(make_pair(x, y));
}
}
}
}
} int main()
{
int Cas;
scanf("%d", &Cas);
while (Cas--) {
scanf("%d %d", &N, &M);
for (int i = 0; i < N; ++i) {
for (int j = 0; j < M; ++j) scanf("%d", &g[i][j]);
}
scanf("%d", &n);
for (int i = 0; i < n; ++i) scanf("%d %d", &point[i].x, &point[i].y); for (int i = 0; i < (1 << n); ++i) {
for (int j = 0; j < n; ++j) dp[i][j] = inf;
} memset(dd, 0x3f, sizeof(dd));
for (int i = 0; i < n; ++i) {
spfa(i);
for (int j = 0; j < n; ++j) {
if (i == j) d[i][j] = 0;
else d[i][j] = dist[point[j].x][point[j].y];
} dp[1 << i][i] = dd[i];
} for (int s = 0; s < (1 << n); ++s) {
for (int i = 0; i < n; ++i) {
if ( dp[s][i] != inf && ((1 << i) & s)) {
for (int j = 0; j < n; ++j) if (i != j && (!((1 << j) &s))) {
dp[s | (1 << j)][j] = min(dp[s | (1 << j)][j], dp[s][i] + d[i][j]);
}
}
}
} int ans = inf;
for (int i = 0; i < n; ++i) {
ans = min(ans, dp[(1 << n) - 1][i] + dd[i] - g[point[i].x][point[i].y]);
} printf("%d\n", ans); }
return 0;
}

hdu 4568 Hunter(spfa预处理 + 状压dp)的更多相关文章

  1. HDU 4568 Hunter 最短路+状压DP

    题意:给一个n*m的格子,格子中有一些数,如果是正整数则为到此格子的花费,如果为-1表示此格子不可到,现在给k个宝藏的地点(k<=13),求一个人从边界外一点进入整个棋盘,然后拿走所有能拿走的宝 ...

  2. loj 1316(spfa预处理+状压dp)

    题目链接:http://acm.hust.edu.cn/vjudge/problem/viewProblem.action?id=27024 题意:求0-(n-1)的经过最多的标记的点的最短路. 思路 ...

  3. HDU 4899 Hero meet devil (状压DP, DP预处理)

    题意:给你一个基因序列s(只有A,T,C,G四个字符,假设长度为n),问长度为m的基因序列s1中与给定的基因序列LCS是0,1......n的有多少个? 思路:最直接的方法是暴力枚举长度为m的串,然后 ...

  4. HDU 6149 Valley Numer II 状压DP

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=6149 题意:中文题目 解法:状压DP,dp[i][j]代表前i个低点,当前高点状态为j的方案数,然后枚 ...

  5. HDU 5434 Peace small elephant 状压dp+矩阵快速幂

    题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=5434 Peace small elephant  Accepts: 38  Submissions: ...

  6. HDU 1074 Doing Homework(状压DP)

    第一次写博客ORZ…… http://acm.split.hdu.edu.cn/showproblem.php?pid=1074 http://acm.hdu.edu.cn/showproblem.p ...

  7. HDU - 4284 Travel(floyd+状压dp)

    Travel PP loves travel. Her dream is to travel around country A which consists of N cities and M roa ...

  8. UVA 1412 Fund Management (预处理+状压dp)

    状压dp,每个状态可以表示为一个n元组,且上限为8,可以用一个九进制来表示状态.但是这样做用数组开不下,用map离散会T. 而实际上很多九进制数很多都是用不上的.因此类似uva 1601 Mornin ...

  9. HDU 4906 Our happy ending (状压DP)

    HDU 4906 Our happy ending pid=4906" style="">题目链接 题意:给定n个数字,每一个数字能够是0-l,要选当中一些数字.然 ...

随机推荐

  1. IDEA Error:java: 未结束的字符串文字

    首页 > 编程交流 > 基础篇 > IDEA Error:java: 未结束的字符串文字 201601-25 IDEA Error:java: 未结束的字符串文字   IDEA开发, ...

  2. 一道常考fork题挖掘

    #include <stdio.h> #include <sys/types.h> #include <unistd.h> int main(void) { int ...

  3. Android异步加载访问网络图片-解析json

    来自:http://www.imooc.com/video/7871 推荐大家去学习这个视频,讲解的很不错. 慕课网提供了一个json网址可以用来学习:http://www.imooc.com/api ...

  4. C#中DataTable排序、检索、合并等操作实例

    转载引用至:http://www.jb51.net/article/49222.htm     一.排序1.获取DataTable的默认视图2.对视图设置排序表达式3.用排序后的视图导出的新DataT ...

  5. Gym 100703K Word order 贪心

    题目链接 题意:给定一个长度为n的字符串,字符串仅由"F","N","A"三种字符组成,现有一种操作P,即把两个相邻的字符调换位置.要求把所 ...

  6. JSP题库

    一.    填空题 一个完整的JSP页面是由普通的HTML标记.JSP指令标记.JSP动作标记.  变量声明 与方法声明  .程序片  .表达式  .   注释   7种要素构成. JSP页面的基本构 ...

  7. PCH文件配置路径

    "项目" >> Build  Settings >> Preflx Header >> $(SRCROOT)/项目名/XXX.pch

  8. 使用vsphere client 克隆虚拟机

    免费的VMWare ESXi5.0非常强大,于是在vSphere5.0平台中ESXi取代了ESX.,使用ESXi经常会遇到这样的问题,我需要建立多个虚拟机,都是windows2003操作系统,难道必须 ...

  9. java1.8中Lambda表达式reduce聚合测试例子

    public class LambdaTest { public static void main(String[] args) { // 相当于foreach遍历操作结果值 Integer out ...

  10. 柔性数组 data[0]

    struct MyData {    int nLen;    char data[0];}; 在结构中,data是一个数组名:但该数组没有元素:该数组的真实地址紧随结构体MyData之后,而这个地址 ...