HDU 5067 Harry And Dig Machine(状压dp)

HDU 5067 Harry And Dig Machine

思路:由于点才10个,在加上一个起点,处理出每个点之间的曼哈顿距离,然后用状压dp搞,状态表示为:

dp[i][s],表示在i位置,走过的点集合为s的最小代价

代码:

#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <algorithm>
using namespace std;

const int N = 15;
int n, m;

struct Point {
	int x, y;
	Point() {}
	Point(int x, int y) {
		this->x = x;
		this->y = y;
	}
} p[N];

int pn;

int g[N][N];
int dp[N][(1<<13) + 5];

int dis(Point a, Point b) {
	return abs(a.x - b.x) + abs(a.y - b.y);
}

const int INF = 0x3f3f3f3f;
int main() {
	while (~scanf("%d%d", &n, &m)) {
		pn = 0;
		int a;
		int flag = 0;
		int zero;
		for (int i = 0; i < n; i++) {
			for (int j = 0; j < m; j++) {
				scanf("%d", &a);
				if (a) {
					p[pn++] = Point(i, j);
					if (i == 0 && j == 0) {
						flag = 1;
						zero = pn - 1;
					}
				}
			}
		}
		if (!flag) {
			zero = pn;
			p[pn++] = Point(0, 0);
		}
		for (int i = 0; i < pn; i++) {
			for (int j = i; j < pn; j++) {
				g[i][j] = g[j][i] = dis(p[i], p[j]);
			}
		}
		for (int i = 0; i < pn; i++)
			for (int j = 0; j < (1<<pn); j++)
				dp[i][j] = INF;

		dp[zero][0] = 0;
		dp[zero][(1<<zero)] = 0;
		int ss = (1<<pn);
		for (int i = 0; i < ss; i++) {
			for (int j = 0; j < pn; j++) {
				if (i&(1<<j)) {
					for (int k = 0; k < pn; k++) {
						if (i&(1<<k)) {
							dp[j][i] = min(dp[j][i], dp[k][i^(1<<j)] + g[j][k]);
						}
					}
				}
			}
		}
		int ans = INF;
		for (int i = 0; i < pn; i++)
			ans = min(ans, dp[i][(1<<pn) - 1] + g[zero][i]);
		printf("%d\n", ans);
	}
	return 0;
}
时间: 2024-08-24 03:06:08

HDU 5067 Harry And Dig Machine(状压dp)的相关文章

HDU 5067 Harry And Dig Machine(状压DP)(TSP问题)

题目地址:pid=5067">HDU 5067 经典的TSP旅行商问题模型. 状压DP. 先分别预处理出来每两个石子堆的距离.然后将题目转化成10个城市每一个城市至少经过一次的最短时间模型.然后简单的状压DP就可以. 代码例如以下: #include <iostream> #include <cstdio> #include <string> #include <cstring> #include <stdlib.h> #incl

HDU 5067 Harry And Dig Machine(状压dp)

感觉这两天怎么老是遇到状压啊.... 数字20以下,首想状压啊... 不过这题犯抽忘记考虑没有石头的时候了啊. 简单的状压:表示状态为j时以第i的作为结束. PS:这题也在表扬大蓝翔的挖掘机技术啊.醉了啊... Harry And Dig Machine Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 468    Accepted S

HDOJ 5067 Harry And Dig Machine 状压DP

状压DP....dp[i][j]已经走过的点的状态,目前再j点的最小距离 Harry And Dig Machine Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 560    Accepted Submission(s): 210 Problem Description As we all know, Harry Porter le

hdu 5067 Harry And Dig Machine (状态压缩dp)

题目链接 bc上的一道题,刚开始想用这个方法做的,因为刚刚做了一个类似的题,但是想到这只是bc的第二题, 以为用bfs水一下就过去了,结果MLE了,因为bfs的队列里的状态太多了,耗内存太厉害. 题意: 从某一点出发,遍历网格上的一些点,每个点至少访问一次需要的最小时间是多少. 官方题解: 由于Harry的dig machine是无限大的,而装载石头和卸载石头是不费时间的,所以问题可以转化成:从某一点出发,遍历网格上的一些点,每个点至少访问一次需要的最小时间是多少.这就是经典的旅行商问题,考虑到

HDU 4856 Tunnels (最短路+状压DP)

题意:给你N*N的网格,'.'表示可以走,'#'表示不能走,m条管道,每条管道有起点和终点坐标, Bob每次可以走到相邻的网格花费1s,问Bob走完m条管道要花多少时间:Bob在管道内不计算时间 即计算Bob从管道 i 的出口走到管道 j 的入口的时间Dis(e[i],s[j])的最小和,起点可以任意: 思路:看了题解说是状态压缩DP然后深入理解了下. 首先算出d[e[i]][s[j]]的最短距离,不能到达为-1: dp[i][j] : 表示以 j 为起点状态为 i 的最小值.其中 i 是用十进

hdu 5067 Harry And Dig Machine(BestCoder Round #14)

Harry And Dig Machine Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 332    Accepted Submission(s): 104 Problem Description As we all know, Harry Porter learns magic at Hogwarts School. Howeve

HDU 1074:Doing Homework(状压DP)

http://acm.hdu.edu.cn/showproblem.php?pid=1074 Doing Homework Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total Submission(s): 7704    Accepted Submission(s): 3484 Problem Description Ignatius has just come bac

HDU 6149 Valley Numer II(状压DP)

题目链接 HDU6149 百度之星复赛的题目……比赛的时候并没有做出来. 由于低点只有15个,所以我们可以考虑状压DP. 利用01背包的思想,依次考虑每个低点,然后枚举每个状态. 在每个状态里面任意枚举不在这个状态中的两个点,如果能构成一个valley,那么更新答案. #include <bits/stdc++.h> using namespace std; #define rep(i, a, b) for (int i(a); i <= (b); ++i) #define dec(i,

hdu 2167 方格取数 【状压dp】(经典)

<题目链接> 题目大意: 给出一些数字组成的n*n阶矩阵,这些数字都在[10,99]内,并且这个矩阵的  3<=n<=15,从这个矩阵中随机取出一些数字,在取完某个数字后,该数字周围8个点都不能取,问:取得数字的最大和为多少? 解题分析: 由于对每一个数,有选和不选两种可能,分别对应状态压缩中的1和0,且 n<=15,1<<15不是非常大,因此就可以非常自然的想到状态压缩. 此题要与普通的状压dp不同的是,当某一行取某种方案时,如何求出这种取数的所有取得的数之和,