POJ2686 Traveling by Stagecoach(状压DP)
题意:
有一个旅行家计划乘马车旅行。他所在的国家里共有m个城市,在城市之间有若干道路相连。从某个城市沿着某条道路到相邻的城市需要乘坐马车。而乘坐马车需要使用车票,每用一张车票只可以通过一条道路。每张车票上都记有马的匹数,从一个城市移动到另一个城市的所需时间等于城市之间道路的长度除以马的数量的结果。这位旅行家一共有n张车票,第i张车票上马的匹数是ti。一张车票只能使用一次,并且换乘所需要的时间可以忽略。求从城市a到城市b所需要的最短时间。如果无法到达城市b则输出”Impossible”。
分析:
一道经典的状态压缩DP,例如当前状态为“现在在城市V,此时还剩下的车票集合为S".从此状态出发,使用一张在S集合里面的车票i ,就可以转移到城市U".
dp[S][v]含义:旅行家还剩余的马车票组成集合S,并且已到达城市v的时候所花的时间总和。若目前已到达城市v,且马车票组成的集合为S,此时使用集合S中的第i张马车票到达城市u,那么状态转移过程可以表示为:
dp[S&~(1<<i)][u]=min{dp[S&~(1<<i)][u],dp[s][v]+d[s][v]/t[i]};
AC
#include <cstdio>
#include <algorithm>
#include <cstring>
using namespace std;
const int maxn = << ;
const int maxm = ;
const int INF = << ; int n, m, p, a, b;
int t[maxm];
int d[maxm][maxm]; //图的邻接矩阵表示(-1表示没有边)
double dp[maxn][maxm];
//dp[S][v] := 到达剩下的车票集合为S并且现在在城市v的状态所需要的最小花费
void so()
{
for (int i = ; i < ( << n); i++)
fill(dp[i], dp[i] + m + , INF); //用足够大的值初始化 dp[( << n) - ][a] = ;
double res = INF;
for (int i = ( << n) - ; i >= ; i--){//枚举票的状态
for (int u = ; u <= m; u++){//起点u
for (int j = ; j < n; j++){//枚举每种票的情况
if (i & ( << j)){//当前票的状态中有第j票
for (int v = ; v <= m; v++){//枚举可以去到的城市
if (d[v][u]){
//使用车票i,从v移动到u
dp[i & ~( << j)][v] = min(dp[i & ~( << j)][v], dp[i][u] + (double)d[u][v] / t[j]);
}
}
}
}
}
}
for (int i = ; i < ( << n); i++)
res = min(res, dp[i][b]);
if (res == INF)
//无法到达
printf("Impossible\n");
else
printf("%.3f\n", res); }
int main( )
{ while(scanf("%d%d%d%d%d",&n,&m,&p,&a,&b)!=EOF)
{
if(n==&&m==)
break;
memset(d,,sizeof(d));
for(int i= ; i<n ; i++)
scanf("%d",&t[i]);
while(p--)
{
int u,v,w;
scanf("%d%d%d",&u,&v,&w);
d[v][u]=d[u][v]=w;
}
so( );
}
return ;
}
POJ2686 Traveling by Stagecoach(状压DP)的更多相关文章
- POJ 2686 Traveling by Stagecoach (状压DP)
题意:有一个人从某个城市要到另一个城市, 有n个马车票,相邻的两个城市走的话要消耗掉一个马车票.花费的时间呢,是马车票上有个速率值 ,问最后这个人花费的最短时间是多少. 析:和TSP问题差不多,dp[ ...
- Traveling by Stagecoach /// 状压DP oj22914
题目大意: 输入n,m,p,a,b n是车票数(1<=n<=8),m是城市数(2<=m<=30) p是路径数(可能为0),a是起点,b是终点 接下来一行有n个数 为每张车票的马 ...
- POJ 2686 Traveling by Stagecoach 壮压DP
大意是有一个人从某个城市要到另一个城市(点数<=30) 然后有n个马车票,相邻的两个城市走的话要消耗掉一个马车票. 花费的时间呢,是马车票上有个速率值,用边/速率就是花的时间. 问最后这个人花费 ...
- POJ2686 Traveling by Stagecoach 状态压缩DP
POJ2686 比较简单的 状态压缩DP 注意DP方程转移时,新的状态必然数值上小于当前状态,故最外层循环为状态从大到小即可. #include <cstdio> #include < ...
- 【状压DP】poj2686 Traveling by Stagecoach
状压DP裸题,将({当前车票集合},当前顶点)这样一个二元组当成状态,然后 边权/马匹 当成边长,跑最短路或者DAG上的DP即可. #include<cstdio> #include< ...
- poj3311 TSP经典状压dp(Traveling Saleman Problem)
题目链接:http://poj.org/problem?id=3311 题意:一个人到一些地方送披萨,要求找到一条路径能够遍历每一个城市后返回出发点,并且路径距离最短.最后输出最短距离即可.注意:每一 ...
- codeforces 21D. Traveling Graph 状压dp
题目链接 题目大意: 给一个无向图, n个点m条边, 每条边有权值, 问你从1出发, 每条边至少走一次, 最终回到点1. 所走的距离最短是多少. 如果这个图是一个欧拉回路, 即所有点的度数为偶数. 那 ...
- poj2686 状压dp入门
状压dp第一题:很多东西没看懂,慢慢来,状压dp主要运用了位运算,二进制处理 集合{0,1,2,3,....,n-1}的子集可以用下面的方法编码成整数 像这样,一些集合运算就可以用如下的方法来操作: ...
- TSP问题之状压dp法
首先,我们先来认识一下什么叫做TSP问题 旅行商问题,即TSP问题(Traveling Salesman Problem)又译为旅行推销员问题.货郎担问题,是数学领域中著名问题之一.假设有一个旅行商人 ...
- BZOJ 1087: [SCOI2005]互不侵犯King [状压DP]
1087: [SCOI2005]互不侵犯King Time Limit: 10 Sec Memory Limit: 162 MBSubmit: 3336 Solved: 1936[Submit][ ...
随机推荐
- hadoop再次集群搭建(1)-安装系统
从8月份到现在12月份,中间有四个月的时间没有学习hadoop系统了.其实适应新的环境,到现在一切尘埃落定,就应该静下心来,好好学习一下hadoop以及我之前很想学习的mahout.个人对算法比较感兴 ...
- Android中SQLite查询date类型字段出现有返回但是为错误值的情况
出现该情况的原因是因为查询精度与数据库中存储精度不相同造成的,例如,查询精度为 YYYY-MM-DD 但是存储精度为 YYYY-MM-DD HH:MM:SS,就会出现该错误. 更改查询精度为YYYY- ...
- [Elasticsearch2.x] 多字段搜索 (一) - 多个及单个查询字符串 <译>
多字段搜索(Multifield Search) 本文翻译自官方指南的Multifield Search一章. 查询很少是只拥有一个match查询子句的查询.我们经常需要对一个或者多个字段使用相同或者 ...
- php验证是否建立数据库,否,则自动建立
<?php /* 默认建立的数据库为test,数据表为admin,管理员只需要修改DB_PWD(即本地的服务器密码)即可,用户密码采用md5加密 */ define(DB_HOST," ...
- NSButton添加事件
-(void)addButton { NSButton* pushButton = [[NSButton alloc] initWithFrame: NSMakeRect(, , , )]; push ...
- spoj1716 Can you answer these queries III
传送门 (分析见正睿2018.10.1笔记) 代码 #include<iostream> #include<cstdio> #include<cstring> #i ...
- (转)Linux操作系统下VMware的多网卡桥接转换
VMware,鼎鼎大名的虚拟机软件,没有人不知道吧?当然,在Linux下使用虚拟机软件,并不一定需要使用VMWare,Xen也是非常不错的选择,有很多评测就认为XEN的表现优于VMware.可惜的是X ...
- java全栈day34---表单CSS
今日内容介绍 1 使用html的表单标签编写“注册页面” 2 使用DIV和CSS重写网站首页 所有的html标签中,表单标签是最重要的.在实际开发中,最经典的实例就是用户注册,覆盖 了表单标签的所有的 ...
- 【LeetCode】将罗马数字转换成10进制数
Roman to Integer Given a roman numeral, convert it to an integer. 首先介绍罗马数字 罗马数字共有七个,即I(1),V(5),X(10) ...
- UCOSIII优先级
优先级 0:中断服务管理任务 OS_IntQTask() 优先级 1:时钟节拍任务 OS_TickTask() 滴答定时器任务 优先级 2:定时任务 OS ...