HDU 5067 Harry And Dig Machine (pressure dp), hdu5067
HDU 5067 Harry And Dig Machine
Idea: because there are only 10 points, a starting point is added to process the Manhattan distance between each point, and then press dp to display the status as follows:
Dp [I] [s] indicates that at the I position, the point set that passes through is the minimum cost of s.
Code:
#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;}