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. Vuex最基本样例

    通过vue-cli建立基本脚手架(需要安装vuex),需要新建一个store.js文件.基本目录如下 1,store.js文件代码: import Vue from 'vue' import Vuex ...

  2. 【小而优】 如何实现 tail -f 动态显示日志时高亮显示关键字

    前言 如果你在linux下工作,那用tail -f跟踪一个日志文件的输出内容应该是家常便饭了. 但是,有时你更关心的是一些敏感字词,希望能够在动态跟踪的同时,把这些字词高亮出来,比如日志中的 ERRO ...

  3. poi解析Excel文件版本问题

    poi解析Excel文件时有两种格式: HSSFWorkbook格式用来解析Excel2003(xls)的文件 XSSFWorkbook格式用来解析Excel2007(xlsx)的文件 如果用HSSF ...

  4. 基于GTID搭建MHA

    一.简介 MHA 是一套优秀的作为MySQL高可用性环境下故障切换和主从提升的高可用软件.在MySQL故障切换过程中,MHA能做到在0~30秒之内自动完成数据库的故障切换操作,并且在进行故障切换的过程 ...

  5. [PostgreSql]PostgreSql调用函数及用IF EXISTS判断表是否存在

    1.创建一个函数function1 -- FUNCTION: public.function1(character varying, integer) -- DROP FUNCTION public. ...

  6. Maven 三种archetype说明

    新建Maven project项目时,需要选择archetype. 那么,什么是archetype? archetype的意思就是模板原型的意思,原型是一个Maven项目模板工具包.一个原型被定义为从 ...

  7. 高性能Go并发

    1.管道chan吞吐极限10,000,000,单次Put,Get耗时大约100ns/op,无论是采用单Go程,还是多Go程并发(并发数:100, 10000, 100000),耗时均没有变化,Go内核 ...

  8. HTTP下载图片

    网上有专门写的http下载的C++代码,但是我发现windows自带的http下载,一行代码就搞定,非常简单,目前为止使用正常. 首先包含头文件和lib文件 #include <urlmon.h ...

  9. (2) iOS开发之UI处理-UILabel篇

    我们经常要根据内容去动态计算控件的高度,比如一个UILabel控件,常常要显示多行内容,并且计算出总高度,如果每个UILabel要多行显示,都要写这么一段代码是非常痛苦的,看代码如下:     我想大 ...

  10. IOS UI-瀑布流(UICollectionView)

    ViewController.m // // ViewController.m // IOS_0227_瀑布流 // // Created by ma c on 16/2/27. // Copyrig ...