hdu 4796 Winter's Coming 插头DP
来源:互联网 发布:javascript是谁发明的 编辑:程序博客网 时间:2024/04/30 04:35
目前OJ上跑的最快 187ms
要求建造城墙把W分在左边,L分在右边,并且上下联通
做法是从地图第一行上面连一个插头下来。DP的最终状态是最后一行连一个插头到下面。
至于W分在左边,L分在右边,做法是:
保证任意一个W左边的下插头为偶数个,L的下插头为奇数个。
具体看代码
#include<stdio.h>#include<string.h>#include<ctype.h>#include<math.h>#include<string>#include<cstdlib>#include<set>#include<map>#include<vector>#include<queue>#include<algorithm>using namespace std;void fre(){freopen("t.txt","r",stdin);}template <class T1, class T2>inline void gmax(T1 &a, T2 b) { if (b>a)a = b; }template <class T1, class T2>inline void gmin(T1 &a, T2 b) { if (b<a)a = b; }#define ls o<<1#define rs o<<1|1#define MS(x,y) memset(x,y,sizeof(x))#define MC(x, y) memcpy(x, y, sizeof(x))typedef long long LL;typedef unsigned int UI;const int Z = 1e9+7,inf = 1e9;template <class T1, class T2>inline void gadd(T1 &a, T2 b) { a+=b; if(a >= Z) a%=Z; }int cas;const int MAXD=15,HASH=30007;const int STATE=1000010;int maze[25][MAXD];int code[MAXD],ch[MAXD];int n,m,ex,ey,ans;struct HASHMAP{ int head[HASH],next[STATE],size; LL state[STATE]; LL f[STATE]; void init() { size=0; memset(head,-1,sizeof(head)); } void push(LL st,LL ans) { int i; int h=st%HASH; for(i=head[h];i!=-1;i=next[i]) if(state[i]==st) { gmin(f[i],ans); return; } state[size]=st; f[size]=ans; next[size]=head[h]; head[h]=size++; }}hm[2];void decode(int *code,int m,LL st)//解码{ for(int i=m;i>=0;i--) { code[i]=st&7; st>>=3; }}LL encode(int *code,int m)//状态压缩{ int cnt=1; MS(ch,-1); ch[0]=0; LL st=0; for(int i=0;i<=m;i++) { if(ch[code[i]]==-1)ch[code[i]]=cnt++; st<<=3; st|=ch[code[i]]; } return st;}void shift(int *code,int m)//换行{ for(int i=m;i>0;i--)code[i]=code[i-1]; code[0]=0;}void dpblank(int i,int j,int cur){ int left,up; for(int k=0;k<hm[cur].size;k++) { decode(code,m,hm[cur].state[k]); left=code[j-1]; up=code[j]; if(left&&up) { if(left != up) { code[j-1]=code[j]=0; for(int t=0;t<=m;t++) if(code[t]==up) code[t]=left; if(j==m)shift(code,m); hm[cur^1].push(encode(code,m),hm[cur].f[k]+maze[i][j]); } } else if(left || up) { int t; if(left) t=left; else t=up; if(maze[i][j+1] >= 0) { code[j-1]=0; code[j]=t; hm[cur^1].push(encode(code,m),hm[cur].f[k] + maze[i][j]); } if(maze[i+1][j] >= 0) { code[j-1]=t; code[j]=0; if(j==m)shift(code,m); hm[cur^1].push(encode(code,m),hm[cur].f[k] + maze[i][j]); } } else { if(j == m) shift(code,m); hm[cur^1].push(encode(code,m),hm[cur].f[k]); if(maze[i][j+1] >= 0&&maze[i+1][j] >= 0) { code[j-1]=code[j]=13; hm[cur^1].push(encode(code,m),hm[cur].f[k] + maze[i][j]); } } }}void dpblock(int i,int j,int cur){ int k; for(k=0;k<hm[cur].size;k++) { decode(code,m,hm[cur].state[k]); if(maze[i][j] == -3)//W的判断 { int c = 0; for(int p = 0; p < j-1; ++p) if(code[p]) c++; if(c&1) continue; } if(maze[i][j] == -2)//L的判断 { int c = 0; for(int p = 0; p < j-1; ++p) if(code[p]) c++; if(c%2 == 0) continue; } code[j-1]=code[j]=0; if(j==m) shift(code,m); hm[cur^1].push(encode(code,m),hm[cur].f[k]); }}void solve(){ int cur=0; ans= inf; hm[cur].init(); MS(code,0); for(int i = 1; i <= m; ++i)//状态转移起点,从上面加一个插头下来 { code[i-1] = 0; code[i] = 13; hm[cur].push(encode(code,m),0); } for(int i=1;i<=n;i++) for(int j=1;j<=m;j++) { hm[cur^1].init(); if(maze[i][j] >= 0) dpblank(i,j,cur); else dpblock(i,j,cur); cur^=1; } for(int i=0;i<hm[cur].size;i++)//统计答案,要求只有一个通往地图下面的插头 { decode(code,m,hm[cur].state[i]); int c = 0;for(int i = 0; i <= m; ++i) if(code[i]) c++; if(c != 1) continue; gmin(ans,hm[cur].f[i]); } if(ans != inf) printf("%d\n",ans); else puts("-1");}char str[MAXD];int main(){ while(scanf("%d%d",&n,&m)!=EOF) { MS(maze,-1); ex=0; for(int i=1;i<=n;i++) { scanf("%s",str+1); for(int j=1;j<=m;j++) { if(str[j] == '#') maze[i][j] = -1; else if(str[j] == 'L') maze[i][j] = -2; else if(str[j] == 'W') maze[i][j] = -3; else maze[i][j] = str[j] - '0'; } } for(int i = 1; i <= m; ++i) maze[n+1][i] = 0; solve(); } return 0;}
1 0
- HDU 4796 Winter's Coming 插头DP
- hdu 4796 Winter's Coming 插头DP
- hdu 1693 插头dp
- hdu 4064 (插头DP)
- HDU-1693-插头dp
- Hdu 1693 插头dp
- hdu 1693 插头DP
- hdu 4804 插头DP
- hdu 1693 插头dp
- hdu 1964 插头dp
- 【插头DP】Tony's Tour
- winter is coming
- The Winter Is Coming
- Winter Is Coming CodeForces
- hdu 1964 Pipes 插头DP
- HDU 4285 circuits[插头DP]
- hdu 4949 Light 插头dp
- hdu 1964 Plan (插头dp)
- poj 3177 Redundant Paths (tarjan)
- Swift学习之条件操作和循环
- oracle 查询大于某个时间的记录
- caffe-fast-rcnn(Caffe、FSRCNN、FastRCNN)
- Kafka剖析(一):Kafka背景及架构介绍
- hdu 4796 Winter's Coming 插头DP
- CSS3 3D transforms系列-3D旋转木马
- Linux操作系统对于系统时间的操作
- cocos2dx ListView 无限循环页
- linux fcntl
- git 常用命令
- Android Studio中R文件丢失
- wex5组件--popMenu
- 菜单Icon的显示