RUAL1519 Formula 1


Background

Regardless of the fact, that Vologda could not get rights to hold the Winter Olympic games of 20**, it is well-known, that the city will conduct one of the Formula 1 events. Surely, for such an important thing a new race circuit should be built as well as hotels, restaurants, international airport - everything for Formula 1 fans, who will flood the city soon. But when all the hotels and a half of the restaurants were built, it appeared, that at the site for the future circuit a lot of gophers lived in their holes. Since we like animals very much, ecologists will never allow to build the race circuit over the holes. So now the mayor is sitting sadly in his office and looking at the map of the circuit with all the holes plotted on it.

Problem

Who will be smart enough to draw a plan of the circuit and keep the city from inevitable disgrace? Of course, only true professionals - battle-hardened programmers from the first team of local technical university!.. But our heroes were not looking for easy life and set much more difficult problem: “Certainly, our mayor will be glad, if we find how many ways of building the circuit are there!” - they said.

It should be said, that the circuit in Vologda is going to be rather simple. It will be a rectangle N*M cells in size with a single circuit segment built through each cell. Each segment should be parallel to one of rectangle’s sides, so only right-angled bends may be on the circuit. At the picture below two samples are given for N = M = 4 (gray squares mean gopher holes, and the bold black line means the race circuit). There are no other ways to build the circuit here.

Input

The first line contains the integer numbers N and M (2 ≤ N, M ≤ 12). Each of the next N lines contains M characters, which are the corresponding cells of the rectangle. Character “.” (full stop) means a cell, where a segment of the race circuit should be built, and character “*” (asterisk) - a cell, where a gopher hole is located. There are at least 4 cells without gopher holes.

Output

You should output the desired number of ways. It is guaranteed, that it does not exceed 263-1.

Samples

Input

4 4

**..

….

….

….

Output

2

Inpuut

4 4

….

….

….

….

Output

6


大概是插头DP的板子题

用Hash表储存状态

然后分别讨论当前的插头所对应的轮廓线上插头的情况

具体的在插头DP的总结里边写一些吧

然后根据已有的插头状态考虑当前位置的情况,大致分为连接,延长,新建三种

然后发现状态比较多,用四进制来进行储存,反正位运算快嘛


#include<bits/stdc++.h>
using namespace std;
#define LL long long
#define MAX 300010
#define N 20
int n,m,ind,endx,endy;
int mp[N][N],tot[2],bit[N];
LL dp[2][MAX],state[2][MAX],sum;
int head[MAX],Next[MAX],Hash[MAX],siz;
/*
tot 状态数
state 每个状态是什么
Hash hash表
*/
void init(){
memset(mp,0,sizeof(mp));
sum=ind=0;
tot[ind]=1;
dp[ind][1]=1;
state[ind][1]=0;
}
void Insert(LL s,LL num){
int pos=s%MAX;
for(int i=head[pos];~i;i=Next[i])
if(state[ind][Hash[i]]==s){dp[ind][Hash[i]]+=num;return;}
++tot[ind];
state[ind][tot[ind]]=s;
dp[ind][tot[ind]]=num;
Hash[siz]=tot[ind];
Next[siz]=head[pos];
head[pos]=siz++;
}
void DP(){
for(int i=1;i<=n;i++){
for(int k=1;k<=tot[ind];k++)state[ind][k]<<=2;
for(int j=1;j<=m;j++){
memset(head,-1,sizeof(head));siz=0;
ind^=1;tot[ind]=0;
for(int k=1;k<=tot[ind^1];k++){
LL s=state[ind^1][k];
LL num=dp[ind^1][k];
int p=(s>>bit[j-1])%4;//左
int q=(s>>bit[j])%4;//上
if(!mp[i][j]){if(p+q==0)Insert(s,num);}
else if(p+q==0){//上左都没有插头
if((!mp[i+1][j])||(!mp[i][j+1]))continue;
s=s+(1<<bit[j-1])+2*(1<<bit[j]);
Insert(s,num);
}else if(p==0&&q){
if(mp[i][j+1])Insert(s,num);
if(mp[i+1][j]){
s=s+q*(1<<bit[j-1])-q*(1<<bit[j]);
Insert(s,num);
}
}else if(p&&q==0){
if(mp[i+1][j])Insert(s,num);
if(mp[i][j+1]){
s=s-p*(1<<bit[j-1])+p*(1<<bit[j]);
Insert(s,num);
}
}else if(p+q==2){
int b=1;
for(int t=j+1;t<=m;t++){
int v=(s>>bit[t])%4;
if(v==1)++b;
if(v==2)--b;
if(!b){s-=(1<<bit[t]);break;}
}
s=s-(1<<bit[j-1])-(1<<bit[j]);
Insert(s,num);
}else if(p+q==4){
int b=1;
for(int t=j-2;t>=0;--t){
int v=(s>>bit[t])%4;
if(v==2)++b;
if(v==1)--b;
if(!b){s+=(1<<bit[t]);break;}
}
s=s-2*(1<<bit[j-1])-2*(1<<bit[j]);
Insert(s,num);
}else if(p==1&&q==2){
if(i==endx&&j==endy)sum+=num;
}else if(p==2&&q==1){
s=s-2*(1<<bit[j-1])-(1<<bit[j]);
Insert(s,num);
}
}
}
}
}
int main(){
for(int i=0;i<N;i++)bit[i]=i<<1;
while(scanf("%d%d",&n,&m)!=EOF){
init();
for(int i=1;i<=n;i++){
getchar();char ch;
for(int j=1;j<=m;j++){
scanf("%c",&ch);
mp[i][j]=(ch=='.');
if(ch=='.')endx=i,endy=j;
}
}
DP();
printf("%lld\n",sum);
}
return 0;
}

RUAL1519 Formula 1 【插头DP】的更多相关文章

  1. 【BZOJ1814】Ural 1519 Formula 1 插头DP

    [BZOJ1814]Ural 1519 Formula 1 题意:一个 m * n 的棋盘,有的格子存在障碍,求经过所有非障碍格子的哈密顿回路个数.(n,m<=12) 题解:插头DP板子题,刷板 ...

  2. 【Ural】1519. Formula 1 插头DP

    [题目]1519. Formula 1 [题意]给定n*m个方格图,有一些障碍格,求非障碍格的哈密顿回路数量.n,m<=12. [算法]插头DP [题解]<基于连通性状态压缩的动态规划问题 ...

  3. bzoj1814 Ural 1519 Formula 1(插头dp模板题)

    1814: Ural 1519 Formula 1 Time Limit: 1 Sec  Memory Limit: 64 MBSubmit: 924  Solved: 351[Submit][Sta ...

  4. URAL1519 Formula 1 —— 插头DP

    题目链接:https://vjudge.net/problem/URAL-1519 1519. Formula 1 Time limit: 1.0 secondMemory limit: 64 MB ...

  5. bzoj 1814 Ural 1519 Formula 1 ——插头DP

    题目:https://www.lydsy.com/JudgeOnline/problem.php?id=1814 普通的插头 DP .但是调了很久.注意如果合并两个 1 的话,不是 “把向右第一个 2 ...

  6. Ural 1519 Formula 1 插头DP

    这是一道经典的插头DP单回路模板题. 用最小表示法来记录连通性,由于二进制的速度,考虑使用8进制. 1.当同时存在左.上插头的时候,需要判断两插头所在连通块是否相同,若相同,只能在最后一个非障碍点相连 ...

  7. [URAL1519] Formula 1 [插头dp入门]

    题面: 传送门 思路: 插头dp基础教程 先理解一下题意:实际上就是要你求这个棋盘中的哈密顿回路个数,障碍不能走 看到这个数据范围,还有回路处理,就想到使用插头dp来做了 观察一下发现,这道题因为都是 ...

  8. URAL Formula 1 ——插头DP

    [题目分析] 一直听说这是插头DP入门题目. 难到爆炸. 写了2h,各种大常数,ural垫底. [代码] #include <cstdio> #include <cstring> ...

  9. bzoj 1814 Ural 1519 Formula 1 插头DP

    1814: Ural 1519 Formula 1 Time Limit: 1 Sec  Memory Limit: 64 MBSubmit: 942  Solved: 356[Submit][Sta ...

  10. BZOJ1814: Ural 1519 Formula 1(插头Dp)

    Description Regardless of the fact, that Vologda could not get rights to hold the Winter Olympic gam ...

随机推荐

  1. imagemagick在windows下安装(转,有改动)

    原文地址:http://blog.csdn.net/royal_coffee/article/details/1602933 注意:本補述僅提供 Windows 下安裝建議. 1. 到 http:// ...

  2. KVM irqfd and ioeventfd

    In previous article vhost architecture we mentioned that vhost and the guest signal each other by ir ...

  3. angularjs1 自定义图片查看器(可旋转、放大、缩小、拖拽)

    笔记: angularjs1 制作自定义图片查看器(可旋转.放大.缩小.拖拽) 2018-01-12 更新  可以在我的博客  查看我 已经封装好的 纯 js写的图片查看器插件    博客链接 懒得把 ...

  4. Warsaw U Contest Petrozavo dsk Summer 2011 Training Camp, Monday, September 5, 2011

    Warsaw U Contest Petrozavo dsk Summer 2011 Training Camp, Monday, September 5, 2011 Problem A.Chocol ...

  5. [spring mvc]Hello World入门

    1.新建项目 File->New->Other,选择Dynamic web project: 项目建好之后,目录结构如下: 2.WEB-INF/web.xml 中配置 dispatcher ...

  6. 搭建selenium + Python环境的总结:

    安装Python+Selenium 写博客是一个不错的选择,首先,是担心自己忘掉,其次,可以供大家做一个参考: 其实,这是自己第一次搭建Python环境(之前用了一周的Idle),还是比较容易的吧: ...

  7. slim(4621✨)

    用于代码瘦身. 老鸟建议:不要混写js 和 html,如果避免不了,当前文件可以改为erb格式,混用slim和erb不是什么问题. git:  https://github.com/slim-temp ...

  8. Codeforces Round #409

    第一题很水但是wa了一发,因为没考虑K前面是K的情况 #include<map> #include<set> #include<cmath> #include< ...

  9. 6.你以为你真的了解final吗?

    1. final的简介 final可以修饰变量,方法和类,用于表示所修饰的内容一旦赋值之后就不会再被改变,比如String类就是一个final类型的类.即使能够知道final具体的使用方法,我想对fi ...

  10. day39 算法基础

    参考博客: http://www.cnblogs.com/alex3714/articles/5474411.html http://www.cnblogs.com/wupeiqi/articles/ ...