[caioj]1489: 基于连通性状态压缩的动态规划问题:Formula 1
来源:互联网 发布:linux man pages 编辑:程序博客网 时间:2024/05/22 06:25
【题目描述】
给你一个 n *m 的棋盘,有的格子是障碍,问共有多少条能经过每个非障碍格子恰好一次的回路(n,m ≤ 12),回路只能有一条。
插头DP入门题,入门建议结合cdq的论文,各种blog,代码学习。
注意事项:
1、要用hash,虽然算出来的状态没有这么多,但是在行与行之间转移状态的时候,会新增很多状态,所以用hash。
2、虽然只有0、1、2三个数,但是状态一般用四进制数存储,因为方便更改、查询某一位。
3、一定要把边界设为障碍点!
代码:
#include<cstdio>#include<cstring>#include<iostream>#include<algorithm>using namespace std;#define LL long longconst int mod=100037;int n,m,map[15][15],xx=-1,yy,now=0,list[2][mod],num[2];// 状态列表 状态总数 LL state[2][mod],ans=0;//每种状态的数目int HASH[mod];LL get(int s,int p)//获取状态s从右向左数的第p位 {return (s>>((p-1)*2))&3;}void change(int &s,int p,int v)//把状态s的第p位改成v { s^=get(s,p)<<((p-1)*2); s^=(v)<<((p-1)*2);}void add(int now,int st,LL sum){ int ss=st%mod; while(list[now][HASH[ss]]!=st&&HASH[ss]!=-1) { ss++;ss%=mod; if(ss==0)ss=1; } if(HASH[ss]==-1) { HASH[ss]=++num[now]; list[now][num[now]]=st; state[now][num[now]]=sum; } else state[now][HASH[ss]]+=sum;}void work(){ state[0][1]=1;num[0]=1;list[0][1]=0; for(int i=1;i<=n;i++) { for(int j=1;j<=m;j++) { now^=1; num[now]=0; memset(HASH,-1,sizeof(HASH)); for(int k=1;k<=num[now^1];k++) { int st=list[now^1][k];//获取上次的状态 LL sum=state[now^1][k];//获取此状态的数目 int p=get(st,j);//获取上次的两个插头 int q=get(st,j+1); if(!map[i][j])//障碍点 { if(!p&&!q)add(now,st,sum); continue; } if(!p&&!q)//没有连到当前的格子 { if(map[i][j+1]&&map[i+1][j]) { change(st,j,1); change(st,j+1,2); add(now,st,sum); } } else if(!p&&q) { if(map[i][j+1])add(now,st,sum); if(map[i+1][j]) { change(st,j,q); change(st,j+1,0); add(now,st,sum); } } else if(p>0&&!q) { if(map[i+1][j])add(now,st,sum); if(map[i][j+1]) { change(st,j,0); change(st,j+1,p); add(now,st,sum); } } else if(p==1&&q==2) { if(i==xx&&j==yy) ans+=sum; } else if(p==2&&q==1) { change(st,j,0); change(st,j+1,0); add(now,st,sum); } else if(p==1&&q==1) { int top=1; for(int pos=j+2;pos<=m+1;pos++) { int temp=get(st,pos); if(temp==1)top++; if(temp==2)top--; if(top==0) { change(st,j,0); change(st,j+1,0); change(st,pos,1); add(now,st,sum); break; } } } else if(p==2&&q==2) { int top=1; for(int pos=j-1;pos;pos--) { int temp=get(st,pos); if(temp==2)top++; if(temp==1)top--; if(top==0) { change(st,j,0); change(st,j+1,0); change(st,pos,2); add(now,st,sum); break; } } } } } for(int j=1;j<=num[now];j++)list[now][j]<<=2; }}int main(){ memset(map,0,sizeof(map)); scanf("%d%d",&n,&m); for(int i=1;i<=n;i++) { char str[15]; scanf("%s",str); for(int j=1;j<=m;j++) { if(str[j-1]=='.') map[i][j]=1,xx=i,yy=j; } } if(xx==-1){puts("0");return 0;} work(); printf("%lld",ans);}
阅读全文
2 0
- [caioj]1489: 基于连通性状态压缩的动态规划问题:Formula 1
- 【caioj】1489: 基于连通性状态压缩的动态规划问题:Formula 1 Ural1519
- [caioj]1490: 基于连通性状态压缩的动态规划问题:Eat the Trees
- [caioj]1491: 基于连通性状态压缩的动态规划问题:Tony's Tour
- [caioj]1492: 基于连通性状态压缩的动态规划问题:Pipes
- [caioj]1491: 基于连通性状态压缩的动态规划问题:Tony's Tour
- [caioj]1493: 基于连通性状态压缩的动态规划问题:Plan
- [caioj]1493: 基于连通性状态压缩的动态规划问题:Plan
- Ural 1519 Formula 1 基于连通性的状态压缩动态规划
- 基于连通性状态压缩的动态规划问题
- 动态规划专题:算法合集之《基于连通性状态压缩动态规划问题》
- 男人8题之Tony's TourPKU1739基于连通性状态压缩的动态规划
- 基于连通性状态压缩的动态规划--【插头DP】模板超级详细解释
- POJ1739 基于连通性的状态压缩dp
- 基于连通性的状态压缩DP
- 【动态规划】Formula 1
- 【基于联通性的状态压缩动态规划】
- 状态压缩的动态规划
- FW(固件)库函数RCC_GetClocksFreq()
- vs2015字符格式转换代码
- 数据库优化手段
- 剑指offer——18.二叉树镜像
- Django上静态文件的配置方法
- [caioj]1489: 基于连通性状态压缩的动态规划问题:Formula 1
- pwnable之cmd2 & & shell 命令 绕过技巧
- HDU 6090-Rikka with Graph
- hdu1215
- php架构师之路
- JAVA中String类的intern()方法的作用
- 【数据结构】后缀表达式-->表达式树
- Memcache技术分享:介绍、使用、存储、算法、优化、命中率
- 快速引爆小说流量,日加上千轻轻松松