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