Description
Input
Output
Sample Input
3 4 3 1 4 3 1 2 1 2 10 2 3 30 3 4 20 2 4 4 2 1 3 1 2 3 3 1 3 3 4 1 2 4 2 5 2 4 3 4 1 5 5 1 2 10 2 3 10 3 4 10 1 2 0 1 2 1 8 5 10 1 5 2 7 1 8 4 5 6 3 1 2 5 2 3 4 3 4 7 4 5 3 1 3 25 2 4 23 3 5 22 1 4 45 2 5 51 1 5 99 0 0 0 0 0
Sample Output
30.000 3.667 Impossible Impossible 2.856
Hint
30.0 3.66667 Impossible Impossible 2.85595
题意:m个城市,p条路,告诉你每条路长度,给你n张车票,每张车票都有一个车速。一条路必须要用掉一张车票,时间为距离/车速。求从a到b所需的最短时间。
题解:状态压缩dp,dp[s][v]表示还剩的车票集合为s,在v城市时最短时间,那么
dp[s][v] = min{ dp[s-{i}][u] + d(v, u) }
#include <iostream> #include <sstream> #include <fstream> #include <string> #include <map> #include <vector> #include <list> #include <set> #include <stack> #include <queue> #include <deque> #include <algorithm> #include <functional> #include <iomanip> #include <limits> #include <new> #include <utility> #include <iterator> #include <cstdio> #include <cstdlib> #include <cstring> #include <cctype> #include <cmath> #include <ctime> using namespace std; const int INF = 0x3f3f3f3f; const int maxn = 10; const int maxm = 35; double dp[(1<<maxn)-1][maxm]; int d[maxm][maxm]; int t[maxn]; int vis[maxm]; int n, m, p, a, b; double rec(int s, int v) { vis[v] = 1; if (dp[s][v] >= 0) return dp[s][v]; if (v == b) return dp[s][v] = 0; double res = INF; for (int u = 0; u < m; ++u) for (int i = 0; i < n; ++i) if (u != v && !vis[u] && (1<<i)&s && d[u][v] < INF) { vis[u] = 1; res = min(res, rec((1<<i)^s, u)+d[v][u]*1.0/t[i]); vis[u] = 0; } return dp[s][v] = res; } int main() { while (cin >> n >> m >> p >> a >> b && (n || m || p || a || b)) { a--; b--; for (int i = 0; i < n; ++i) scanf("%d", &t[i]); fill(d[0], d[m], INF); fill(vis, vis+m, 0); fill(dp[0], dp[1<<n], -1); while (p--) { int x, y, dis; scanf("%d%d%d", &x, &y, &dis); d[x-1][y-1] = d[y-1][x-1] = dis; } double ans = rec((1<<n)-1, a); if (fabs(ans-INF) < 1e-8) printf("Impossible\n"); else printf("%.3f\n", ans); } return 0; }
版权声明:本文为博主原创文章,转载请注明出处。
poj2686(Traveling by Stagecoach)状态压缩dp
原文地址:http://blog.csdn.net/god_weiyang/article/details/47782345