HDU 4114 Disney's FastPass(状压dp)
来源:互联网 发布:管家婆普及版数据恢复 编辑:程序博客网 时间:2024/06/06 00:39
题意就是给你一些点,有的地方有景区,有的地方有某些景点的优先票,拿优先票去景点和不拿的时间不一样。问从地点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 GLQ freopen("input.txt","r",stdin);// freopen("o.txt","w",stdout);#endif int 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;}
0 0
- HDU 4114 Disney's FastPass(状压dp)
- hdu 4114 Disney's FastPass 状压dp
- Hdu 4114 Disney's FastPass(状压dp)
- hdu 4114 Disney's FastPass 状压dp+floyd
- hdu 4114 Disney's FastPass
- HDU 4114 Disney's FastPass(floyd+状态压缩DP)
- HDU Disney's FastPass
- HDU 4114 Disney's FastPass Time
- hdu Disney's FastPass(状态压缩dp)
- HDU Disney's FastPass(状态压缩DP)
- hdu4114.Disney's FastPass
- HDU4114 Disney's FastPass(floyd+状态压缩DP)旅游问题升级(难)
- HDU 2142 - disney
- hdu 2142 disney
- hdu 2142 disney(模拟)
- hdu 1242 disney (map模拟)
- Disney
- hdu 4114(状压dp)
- java IO详解看完你就懂了耐心点。
- Node入门之一
- UITableableview上拉下拉刷新
- 迷宫BFS+递归回溯找爹打印路径
- hihoCoder 二分·二分查找之k小数
- HDU 4114 Disney's FastPass(状压dp)
- 迷宫DFS
- 路由事件初级案例
- poj 3080 Blue Jeans (多串最长公共子串 暴力)
- IIS7.5 错误代码0x8007007e HTTP 错误 500.19
- Androidapi.JNI.Net.Wifi
- 容器第八课,数据存储综合练习,javabean的介绍
- Ibatis学习笔记
- Android_SDCard 的读写权限设置