HDU 4114 Disney's FastPass(状压dp)
题意就是给你一些点,有的地方有景区,有的地方有某些景点的优先票,拿优先票去景点和不拿的时间不一样。问从地点1出发去所有景点再回来的最短时间。
得把景点,景区进行状压。即dp[i][j][k]代表参观景点状态为i,景区状态为j,停在k的最短时间。
先floyd一下处理出最短路。
对于一种状态i,j,为了保证dp[i][j][k]在递推的时候是最短时间可以先用2个(1-n)for循环进行更新,因为可能有的位置的状态是-1即不存在。事实上只要有一个点存在i与j的状态,那么其他点必定都存在i,j这个状态。
然后再去更新去看景点的情况,在做过刚才那个处理后,其实只需要看当前位置下的景点就行,看网上其他人的代码则是遍历去看所有景点,如果这样做的话就不用先做那个处理了,可以放在一起做。
另外,还有一个优化,如果已经参观了那个节点,那么就强行给他一个票,其实就是在其他条件都相同的情况下(在同一个点,经过同样的景点),有票跟没票的比较。这样的话,参观景点的集合就是票的集合的子集了。然后又容易看出其实i跟j的递推顺序交换也是一样的,所以就用了枚举子集的办法,然后把子集从小到大推。
竟然刷到rank1了。577ms。
AC代码:
#include<cstdio>
#include<ctype.h>
#include<algorithm>
#include<iostream>
#include<cstring>
#include<vector>
#include<cstdlib>
#include<stack>
#include<queue>
#include<set>
#include<map>
#include<cmath>
#include<ctime>
#include<string.h>
#include<string>
#include<sstream>
#include<bitset>
using namespace std;
#define ll __int64
#define ull unsigned long long
#define eps 1e-8
#define NMAX 1<<29
#define MOD 1000000
#define lson l,mid,rt<<1
#define rson mid+1,r,rt<<1|1
#define PI acos(-1)
template<class T>
inline void scan_d(T &ret)
{char c;int flag = 0;ret=0;while(((c=getchar())<'0'||c>'9')&&c!='-');if(c == '-'){flag = 1;c = getchar();}while(c>='0'&&c<='9') ret=ret*10+(c-'0'),c=getchar();if(flag) ret = -ret;
}int dp[1<<8][1<<8][55],dist[55][55];struct node
{int t,ft;
};
node no[10];inline void update(int &a, int b)
{if(a < 0 || a > b)a = b;
}void floyd(int n)
{for(int k = 1; k <= n; k++)for(int i = 1; i <= n; i++)for(int j = 1; j <= n; j++)dist[i][j] = min(dist[i][j],dist[i][k]+dist[k][j]);
}int pos[10],getft[55];
int s[1<<8];
int main()
{
#ifdef GLQfreopen("input.txt","r",stdin);
// freopen("o.txt","w",stdout);
#endifint t,n,m,K,cas = 1;scanf("%d",&t);while(t--){scanf("%d%d%d",&n,&m,&K);for(int i = 1; i <= n; i++){for(int j = 1; j <= n; j++)dist[i][j] = NMAX;dist[i][i] = 0;}for(int i = 1; i <= m; i++){int u,v,w;scanf("%d%d%d",&u,&v,&w);dist[u][v] = dist[v][u] = w;}floyd(n);memset(getft,0,sizeof(getft));for(int i = 0; i < K; i++){int tmp;scanf("%d%d%d%d",&pos[i],&no[i].t,&no[i].ft,&tmp);while(tmp--){int t1;scanf("%d",&t1);getft[t1] |= (1<<i);}}for(int i = 0; i < (1<<K); i++)for(int j = 0; j < (1<<K); j++)for(int k = 1; k <= n; k++) dp[i][j][k] = -1;dp[0][0][1] = 0;for(int j = 0; j < (1<<K); j++){int nct = 0;for(int i = j; i ; i = (i-1)&j) s[nct++] = i;s[nct++] = 0;for(int w = nct-1; w >= 0; w--){int i = s[w];for(int k = 1; k <= n; k++) if(dp[i][j][k] >= 0){for(int l = 0; l < K; l++) if(!(i&(1<<l))){int cost = dist[k][pos[l]];if(j&(1<<l)) cost += no[l].ft;else cost += no[l].t;update(dp[i|(1<<l)][j|getft[pos[l]]|(1<<l)][pos[l]],dp[i][j][k]+cost);}for(int l = 1; l <= n; l++)update(dp[i][j|getft[l]][l],dp[i][j][k]+dist[k][l]);}
// for(int k = 1; k <= n; k++) if(dp[i][j][k] >= 0)//这种递推就可以只看自己点上面的景点
// {
// for(int l = 1; l <= n; l++)
// update(dp[i][j|getft[l]][l],dp[i][j][k]+dist[k][l]);
// }
// for(int k = 1; k <= n; k++) if(dp[i][j][k] >= 0)
// {
// for(int l = 0; l < K; l++) if(!(i&(1<<l)))
// {
// if(pos[l] != k) continue;
// int cost;
// if(j&(1<<l)) cost = no[l].ft;
// else cost = no[l].t;
// update(dp[i|(1<<l)][j|getft[pos[l]]|(1<<l)][pos[l]],dp[i][j][k]+cost);
// }
// }}}printf("Case #%d: %d\n",cas++,dp[(1<<K)-1][(1<<K)-1][1]);}return 0;
}
HDU 4114 Disney's FastPass(状压dp)相关推荐
- hdu 4114 Disney's FastPass 状压dp
点击打开链接 题意: 游戏园里有N个区域,有M条边连接这N个区域,有K个要访问的景点.对于每个景点告诉你这个景点所在的区域,要访问这个景点需要等待一定时间,如果没有FastPass,等待时间有Ti,否 ...
- 【LDU】 Week2自测 Disney‘s FastPass | 状压dp、Floyd
这题是hdu 4114... 跟着19的打了打周测,发现个好题 写了写还wa了一发 题目大意: 给出n个点,k个要旅游的景点,然后给出k个景点的信息(位置,t,ft,门票所在地点),t于ft表示,如果 ...
- HDU - 4856 Tunnels (预处理+状压dp)
HDU - 4856 Tunnels (预处理+状压dp) [hud链接] [vj链接] 题目 Problem Description Bob is travelling in Xi'an. He f ...
- HDU 5691 Sitting in Line 状压dp
Sitting in Line 题目连接: http://acm.hdu.edu.cn/showproblem.php?pid=5691 Description 度度熊是他同时代中最伟大的数学家,一切 ...
- HDU 4114 Disney's FastPass
传送门 状压dp+最短路. 一个无向图,接下来给出一些兴趣点,每个兴趣点被访问时有一定耗时.找一条从起点开始访问所有兴趣点再回到起点耗时最短的路(必须访问所有兴趣点,途中可以经过任意点(经过任意点包括 ...
- HDU 4899 Hero meet devil (状压DP, DP预处理)
题意:给你一个基因序列s(只有A,T,C,G四个字符,假设长度为n),问长度为m的基因序列s1中与给定的基因序列LCS是0,1......n的有多少个? 思路:最直接的方法是暴力枚举长度为m的串,然后 ...
- HDU 3001 Travelling (三进制状压dp)
题意 n(n<=10)n(n个城市,知道每个城市间的旅行费用,但每个城市最多走两遍.问最小花费是多少 . 也就是每个城市可以走两次的tsp问题. 分析 最多走两次,三进制0 1 2可满足,即用三 ...
- HDU 4856 Tunnels(BFS+状压DP)
HDU 4856 Tunnels 题目链接 题意:给定一些管道.然后管道之间走是不用时间的,陆地上有障碍.陆地上走一步花费时间1,求遍历全部管道须要的最短时间.每一个管道仅仅能走一次 思路:先BFS预 ...
- hdu 4778 Gems Fight! 状压dp
转自wdd :http://blog.csdn.net/u010535824/article/details/38540835 题目链接:hdu 4778 状压DP 用DP[i]表示从i状态选到结束得 ...
最新文章
- python读写二进制文件(读写字节数据)
- 集成学习-Bagging集成学习算法随机森林(Random Forest)
- 索引创建以及优化_1
- wcf http 返回图片
- Linux网络编程一步一步学-select详解
- LeetCode 1243. 数组变换
- 微服务 注册中心的作用_102,谈谈微服务注册中心zookeeperamp;Eureka
- Nginx启动后无法访问页面
- flask-sqlalchemy mysql_flask-sqlalchemy总结
- iframe父页面与子页面之间的传值问题
- 成都哪所专科院校有计算机专业,成都哪些高职院校有计算机应用技术
- 【有限元分析】有限元仿真分析与解析解的结果对比——以阶梯轴的静力分析为例
- 鸿蒙系统怎么设置上网速度,苹果手机上网速度慢怎么办!手把手教你如何解决...
- 最基础硬件学习 | 简单闪烁灯制作
- 复旦大学计算机研究生初试分数线,复旦大学计算机研究生复试分数线
- 腾讯AI Lab发布智能创作助手「文涌 (Effidit)」,用技术助力「文思泉涌」
- 【约瑟夫环】Java实现:100个人开始从1开始报数,每当报数到3,报数3的人离开,求最后留下来人的位置。
- 在J1939中多帧数据如何发送,它是通过TP.CM_BAM和TP_DT报文发送
- angularjs学习总结 详细教程(转载)
- android 获取电流参数,Android编程实现添加低电流提醒功能的方法
热门文章
- android 窗口圆角
- MMC、EMMC、MCP、EMCP区别
- python猜年龄代码_Python实现猜年龄游戏代码实例
- 功能篇------android 实现“摇一摇”功能
- SpringBoot使用JavaMailSender发送邮件:com.sun.mail.smtp.SMTPSendFailedException: 451 MI:SFQ 163 smtp7
- PS快速将白底图片变为透明图片的解决办法
- miui系统android os,color os对比miui 一加手机刷Color OS与MIUI系统体验对比评测
- 网易容器云平台的微服务化实践(一)
- POS接口与GE接口区别
- AD软件PCB转PADS