POJ 1739 Tony's Tour
来源:互联网 发布:河南大学教务网络系统 编辑:程序博客网 时间:2024/06/08 00:44
从左上角到右下角,求经过所有的非障碍格子一次的单回路数。
Sol:
1.在最后两行转化成回路问题。
2.不增加行直接在起点和种点特殊处理就好。
我选择第二种。
#include<iostream>#include<string.h>#include<algorithm>#include<stdio.h>using namespace std;const int MAXD=15;const int HASH=50007;const int STATE=1000010;int N,M;int maze[MAXD][MAXD];int code[MAXD];int ch[MAXD];//最小表示法使用int ex,ey;//最后一个非障碍格子的坐标struct HASHMAP{ int head[HASH],next[STATE],size; long long state[STATE],f[STATE]; void init() { size=0; memset(head,-1,sizeof(head)); } void push(long long st,long long 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 decode(int *code,int m,long long st){ for(int i=m;i>=0;i--) { code[i]=st&7; st>>=3; }}long long encode(int *code,int m){ int cnt=1; memset(ch,-1,sizeof(ch)); ch[0]=0; long long st=0; for(int i=0;i<=m;i++) { if(ch[code[i]]==-1)ch[code[i]]=cnt++; code[i]=ch[code[i]]; st<<=3; st|=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 k,left,up; for(k=0;k<hm[cur].size;k++) { decode(code,M,hm[cur].state[k]); left=code[j-1]; up=code[j]; if((i==N&&j==1)||(i==N&&j==M))//起点和终点 { if((left&&(!up))||((!left)&&up)) { code[j]=code[j-1]=0; if(j==M)shift(code,M); hm[cur^1].push(encode(code,M),hm[cur].f[k]); } else if(left==0&&up==0) { if(maze[i][j+1]) { code[j-1]=0; code[j]=13; hm[cur^1].push(encode(code,M),hm[cur].f[k]); } if(maze[i+1][j]) { code[j-1]=13; code[j]=0; if(j==M)shift(code,M); hm[cur^1].push(encode(code,M),hm[cur].f[k]); } } continue; } if(left&&up) { if(left==up) { continue;//这种情况不能发生 /* if(i==ex&&j==ey)//只能出现在最后一个非障碍格子 { code[j]=code[j-1]=0; if(j==M)shift(code,M); hm[cur^1].push(encode(code,M),hm[cur].f[k]); }*/ } else //不在同一个连通分量则合并 { code[j-1]=code[j]=0; for(int t=0;t<=M;t++) if(code[t]==left) code[t]=up; if(j==M)shift(code,M); hm[cur^1].push(encode(code,M),hm[cur].f[k]); } } else if((left&&(!up))||((!left)&&up)) { int t; if(left)t=left; else t=up; if(maze[i][j+1]) { code[j-1]=0; code[j]=t; hm[cur^1].push(encode(code,M),hm[cur].f[k]); } if(maze[i+1][j]) { code[j-1]=t; code[j]=0; if(j==M)shift(code,M); hm[cur^1].push(encode(code,M),hm[cur].f[k]); } } else { if(maze[i][j+1]&&maze[i+1][j]) { code[j-1]=code[j]=13; hm[cur^1].push(encode(code,M),hm[cur].f[k]); } } }}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]); code[j-1]=code[j]=0; if(j==M)shift(code,M); hm[cur^1].push(encode(code,M),hm[cur].f[k]); }}char str[20];void init(){ memset(maze,0,sizeof(maze)); for(int i=1;i<=N;i++) { scanf("%s",&str); for(int j=0;j<M;j++) if(str[j]=='.') { maze[i][j+1]=1; } }}void solve(){ int i,j,cur=0; hm[cur].init(); hm[cur].push(0,1); for(i=1;i<=N;i++) for(j=1;j<=M;j++) { hm[cur^1].init(); if(maze[i][j])dpblank(i,j,cur); else dpblock(i,j,cur); cur^=1; } long long ans=0; for(int i=0;i<hm[cur].size;i++) ans+=hm[cur].f[i]; printf("%I64d\n",ans);}int main(){ /*freopen("in.txt","r",stdin); freopen("out.txt","w",stdout);*/ while(scanf("%d%d",&N,&M)) { if(N==0&&M==0)break; init(); solve(); } return 0;}
0 0
- poj 1739 Tony's Tour
- poj 1739 Tony's Tour
- POJ 1739 Tony's Tour
- POJ 1739 Tony's Tour
- 【POJ 1739】Tony's Tour
- POJ 1739 Tony's Tour
- POJ-1739:Tony's Tour
- poj 1739 Tony's Tour 插头dp
- poj 1739 Tony's Tour 插头dp
- POJ 1739 Tony's Tour (插头DP)
- poj 1739 Tony's Tour(插头dp)
- POJ 1739 Tony's Tour 插头DP
- poj 1739 Tony's Tour 插头dp
- POJ 1739 Tony's Tour 笔记
- POJ 1739 Tony's Tour 解题报告(插头DP)
- POJ - 1739 Tony's Tour (单回路插头dp)
- poj 1739 Tony's Tour 插头dp模板题
- Tony's Tour poj1739
- Velocity浅析及与Jsp、Freemarker对比
- sap变量的定义
- POJ-1753 Flip Game
- win32 016 图标和光标
- iOS 开发中,多线程编程GCD的常用方法总结
- POJ 1739 Tony's Tour
- reserve_bootmem_node
- android和ios GoogleMap画导航线路图 路径规划(Directions)
- Python 程序员经常犯的 10 个错误
- 当出现在form表单提交后台出现乱码时!
- JS中数组Array的用法{转载}
- 长颈鹿类对动物类的继承 protected继承方式下
- jdom创建xml文件
- Android音频可视化开发案例说明