ZOJ 3466 插头dp
2013-08-14 21:57
309 查看
做这题时直接在上一道题上修改的。
http://blog.csdn.net/chm517/article/details/9968775
还是多条回路的插头dp,四边形改成六边形,需要自己重推。
up,left->up1,up2,left
每个点依旧是两个插头。
http://blog.csdn.net/chm517/article/details/9968775
还是多条回路的插头dp,四边形改成六边形,需要自己重推。
up,left->up1,up2,left
每个点依旧是两个插头。
#include<cstdio> #include<iostream> #include<cstring> #include<algorithm> typedef long long LL; using namespace std; const int N=16; const int HASH=15511; const int STATE=1000000; LL ans; int n,m,mm; int map ; int ex,ey; struct HASHMAP { int head[HASH],next[STATE],size; int state[STATE]; LL f[STATE]; void init() { size=0; memset(head,-1,sizeof(head)); } void push(int st,LL ans) { int i; int h=st%HASH; for(i=head[h];i!=-1;i=next[i]) if(state[i]==st) { f[i]+=ans; return; } state[size]=st; f[size]=ans; next[size]=head[h]; head[h]=size++; } }hm[2]; void shift(int cur) { for(int i=0;i<hm[cur].size;i++) hm[cur].state[i]<<=1; } inline int cp(int p,int i) { return p&(~(1<<i)); } inline int cp(int p,int i,int j) { return p&(~(1<<i))&(~(1<<j)); } inline int cp(int p,int i,int j,int k) { return p&(~(1<<i))&(~(1<<j))&(~(1<<k)); } inline int getp(int p,int i) { return 1&(p>>i); } inline int pp(int i,int k) { return k<<i; } void dp(int i,int j,int cur) { int jj=j*2+i%2; int tt=i%2==0?-1:0; for(int k=0;k<hm[cur].size;k++) {int s=hm[cur].state[k]; LL data=hm[cur].f[k]; int left=getp(s,jj); int up1=getp(s,jj+1); int up2=getp(s,jj+2); int add=left+up1+up2; if (add==0) {if (j+tt>=0) if (map[i+1][j+tt]&&map[i+1][j+tt+1]) hm[cur^1].push(s|pp(jj,1)|pp(jj+1,1),data); if (map[i+1][j+tt+1]&&map[i][j+1]) hm[cur^1].push(s|pp(jj+1,1)|pp(jj+2,1),data); if (j+tt>=0) if (map[i+1][j+tt]&&map[i][j+1]) hm[cur^1].push(s|pp(jj,1)|pp(jj+2,1),data); continue; } if (add==1) {int tmp=cp(s,jj,jj+1,jj+2); if (j+tt>=0) if (map[i+1][j+tt]) hm[cur^1].push(tmp|pp(jj,1),data); if (map[i+1][j+tt+1]) hm[cur^1].push(tmp|pp(jj+1,1),data); if (map[i][j+1]) hm[cur^1].push(tmp|pp(jj+2,1),data); continue; } if (add==2) {hm[cur^1].push(cp(s,jj,jj+1,jj+2),data); if (i==ex&&j==ey) ans+=data; continue; } } } char str[5]; void init() { int x,y; memset(map,0,sizeof(map)); n=8; ex=-1; for (int i=0;i<n;i++) for(int j=0;j<m;j++) map[i][j]=1; while (mm--) { scanf("%s",str); x=str[0]-'A'; y=str[1]-'A'; map[y][m-1-x]=0; } for (int i=0;i<n;i++) for(int j=0;j<m;j++) if (map[i][j]) {ex=i; ey=j;} } void solve() { int cur=0; ans=0; hm[cur].init(); hm[cur].push(0,1); for(int i=0;i<n;i++) {for(int j=0;j<m;j++) if (map[i][j]) { hm[cur^1].init(); dp(i,j,cur); cur^=1; } shift(cur); } printf("%lld\n",ans); } int main() { while(scanf("%d%d",&m,&mm)!=EOF) { init(); if(ex==-1) { printf("1\n"); continue; } solve(); } return 0; }
相关文章推荐
- ZOJ 3466 The Hive II 插头DP
- ZOJ 3466 The Hive II (插头DP,变形)
- ZOJ 3466 The Hive II(插头DP)
- zoj 3466 The Hive II(插头dp)
- ZOJ 3466 The Hive II 解题报告(插头DP)
- zoj 3466(插头DP 多条回路 六边形)
- zoj 3213 Beautiful Meadow(插头dp)
- ZOJ 3256 Tour in the Castle (插头DP求回路个数+矩阵乘法)
- zoj 3213 Beautiful Meadow 插头dp
- zoj 3213(插头DP 一条路径)
- ZOJ 3256 Tour in the Castle 解题报告(插头DP)
- ZOJ 3213 Beautiful Meadow(插头DP-一条路径最大值,不固定头尾)
- ZOJ 3213 Beautiful Meadow(插头DP)
- ZOJ 3256 Tour in the Castle(插头DP-按行递推—矩阵)
- ZOJ 3213 Beautiful Meadow 解题报告(插头DP)
- hdu 3466 (dp)
- 芯片制作(插头DP写法)
- ZOJ 2366 Weird Dissimilarity (简单DP)
- hdu 3466 Proud Merchants(贪心+DP)
- poj 1739(男人八题之插头DP)