Formula 1

题意

在\(n*m\)的矩阵中,有些格子有树,没有树的格子不能到达,找一条回路,吃完所有的树,求有多少种方法。

解法

因为只要一条回路,所以我们必须维护插头的连通性。

具体的可以参照 这位大佬的博客

代码

注意开long long。

#include <cstdio>
#include <cstdlib>
#include <iostream>
#include <cstring>
#include <cctype>
#define del(a,b) memset(a,b,sizeof(a))
using namespace std;
typedef long long ll;
template <typename T>
inline void read(T &x) {
x=0;char c=getchar();T k=1;
while(!isdigit(c)) {if(c=='-') k=-1;c=getchar();}
while(isdigit(c)) {x=x*10+c-'0';c=getchar();}x*=k;
} const int maxn=15;
const int maxhash=100000;
char G[maxn][maxn];
int _hash[maxhash];
ll sta[2][600000],sum[2][600000];
int cur,n,m,en,em;
int tot[2];
int jz[maxn]; void _init() {
read(n),read(m);
for(int i=1;i<=n;i++)
for(int j=1;j<=m;j++) {
cin>>G[i][j];
if(G[i][j]=='.') en=i,em=j;
}
for(int i=1;i<=m;i++) jz[i]=i<<1;
} void hash_insert(ll s,ll data) {
int pos=s%maxhash;
while(_hash[pos]) {
if(sta[cur][_hash[pos]]==s) {
sum[cur][_hash[pos]]+=data;
return;
}
if(++pos==maxhash) pos=0;
}
++tot[cur];
_hash[pos]=tot[cur];
sta[cur][tot[cur]]=s;sum[cur][tot[cur]]=data;
}
ll ans;
void work() {
tot[0]=1;sum[0][1]=1;
for(int i=1;i<=n;i++) {
for(int k=1;k<=tot[cur];k++)
sta[cur][k]=sta[cur][k]<<2;
for(int j=1;j<=m;j++) {
cur^=1;
tot[cur]=0;
del(_hash,0);
del(sta[cur],0);
del(sum[cur],0);
for(int k=1;k<=tot[1-cur];k++) {
ll s=sta[1-cur][k],data=sum[1-cur][k];
int x=(s>>jz[j-1])%4;
int y=(s>>jz[j])%4;
ll temp;
if(G[i][j]!='.') {
if(x==0&&y==0) hash_insert(s,data);
}
else {
if(x==0&&y==0) {
if(G[i][j+1]=='.'&&G[i+1][j]=='.') {
temp=s+1*(1<<jz[j-1])+2*(1<<jz[j]);
hash_insert(temp,data);
}
continue;
}
if(x==0&&y>0) {
if(G[i][j+1]=='.')
hash_insert(s,data);
if(G[i+1][j]=='.') {
temp=s-y*(1<<jz[j])+y*(1<<jz[j-1]);
hash_insert(temp,data);
}
continue;
}
if(x>0&&y==0) {
if(G[i+1][j]=='.')
hash_insert(s,data);
if(G[i][j+1]=='.') {
temp=s-x*(1<<jz[j-1])+x*(1<<jz[j]);
hash_insert(temp,data);
}
continue;
}
if(x==1&&y==1) {
int f=1;
for(int v=j+1;v<=m;v++) {
int fff=(s>>jz[v])%4;
if(fff==1) f++;
if(fff==2) f--;
if(!f) {
temp=s-2*(1<<jz[v])+1*(1<<jz[v]);
break;
}
}
temp=temp-1*(1<<jz[j-1])-1*(1<<jz[j]);
hash_insert(temp,data);
continue;
}
if(x==2&&y==2) {
int f=1;
for(int v=j-2;v>=1;v--) {
int fff=(s>>jz[v])%4;
if(fff==1) f--;
if(fff==2) f++;
if(!f) {
temp=s-1*(1<<jz[v])+2*(1<<jz[v]);
break;
}
}
temp=temp-2*(1<<jz[j-1])-2*(1<<jz[j]);
hash_insert(temp,data);
continue;
}
if(x==2&&y==1) {
temp=s-2*(1<<jz[j-1])-1*(1<<jz[j]);
hash_insert(temp,data);
continue;
}
if(x==1&&y==2) {
if(i==en&&j==em) {
ans+=data;
}
}
}
}
}
}
} int main() {
_init();
work();
printf("%lld\n",ans);
return 0;
}

bzoj 1814 Fornula 1的更多相关文章

  1. 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 ...

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

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

  3. bzoj 1814: Ural 1519 Formula 1 插头dp经典题

    用的括号序列,听说比较快. 然并不会预处理,只会每回暴力找匹配的括号. #include<iostream> #include<cstdio> #include<cstr ...

  4. bzoj 1814: Ural 1519 Formula 1【插头dp】

    设f[i][j][s]为轮廓线推到格子(i,j),状态为s的方案数 括号表示一段线的左端和右端,表示成左括号和右括号,状压的时候用1和2表示,0表示已经闭合 下面的蓝线是黄色格子的轮廓线,dp转移要把 ...

  5. 插头DP题目泛做(为了对应WYD的课件)

    题目1:BZOJ 1814 URAL 1519 Formula 1 题目大意:给定一个N*M的棋盘,上面有障碍格子.求一个经过所有非障碍格子形成的回路的数量. 插头DP入门题.记录连通分量. #inc ...

  6. BZOJ 2127: happiness [最小割]

    2127: happiness Time Limit: 51 Sec  Memory Limit: 259 MBSubmit: 1815  Solved: 878[Submit][Status][Di ...

  7. BZOJ 3275: Number

    3275: Number Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 874  Solved: 371[Submit][Status][Discus ...

  8. BZOJ 2879: [Noi2012]美食节

    2879: [Noi2012]美食节 Time Limit: 10 Sec  Memory Limit: 512 MBSubmit: 1834  Solved: 969[Submit][Status] ...

  9. bzoj 4610 Ceiling Functi

    bzoj 4610 Ceiling Functi Description bzoj上的描述有问题 给出\(n\)个长度为\(k\)的数列,将每个数列构成一个二叉搜索树,问有多少颗形态不同的树. Inp ...

随机推荐

  1. Hbash语句

    下面我们看看HBase Shell的一些基本操作命令,我列出了几个常用的HBase Shell命令,如下:   名称 命令表达式 创建表 create '表名称', '列名称1','列名称2','列名 ...

  2. eclipse debug的时候提示debug Edit Source Lookup path

    原因可能是代码资源包未加载到debug的路径中,解决方法如下: Debug 视图下 ->在调试的线程上 右键单击 ->选择Edit Source Lookup Path ->选择Ad ...

  3. ExtJs之Ext.XTemplate:模板成员函数

    <!DOCTYPE html> <html> <head> <title>ExtJs</title> <meta http-equiv ...

  4. 洛谷—— P1262 间谍网络

    https://www.luogu.org/problem/show?pid=1262 题目描述 由于外国间谍的大量渗入,国家安全正处于高度的危机之中.如果A间谍手中掌握着关于B间谍的犯罪证据,则称A ...

  5. BEGINNING SHAREPOINT&#174; 2013 DEVELOPMENT 第11章节--为Office和SP解决方式开发集成Apps 集成SP和Office App

    BEGINNING SHAREPOINT® 2013 DEVELOPMENT 第11章节--为Office和SP解决方式开发集成Apps  集成SP和Office App         你能够用两种 ...

  6. iOS 相似QQ空间表视图下拉头部视图放大效果实现

    UITableView 是 UIScrollView 的子类. 所以 UIScrollView 的代理方法.在UITableView 上相同可以得到适用. 既然如此那么我们就行知道.在表格下拉的过程中 ...

  7. 从乐视和小米“最火电视”之战 看PR传播策略

        今年的双11够热闹.一方面,阿里.京东.国美.苏宁等电商巨头卯足了劲儿.试图在双11期间斗个你死我活,剑拔弩张的气势超过了以往不论什么一场双11:还有一方面.不少硬件厂商.家电企业也来凑双11 ...

  8. caffe:使用C++来提取任意一张图片的特征

    0x00 关于使用C++接口来提取特征,caffe官方提供了一个extract_features.cpp的例程,但是这个文件的输入是blob数据,即使输入层使用的是ImageData,也需要在depl ...

  9. Regexp-Utils:银行卡号Luhm校验

    ylbtech-Regexp-Utils:银行卡号Luhm校验 1.返回顶部 1.方法 //Description: 银行卡号Luhm校验 //Luhm校验规则:16位银行卡号(19位通用): // ...

  10. BZOJ 4516 后缀数组+ST+set

    写了一半 没了啊啊啊 重新写的 思路: 先不考虑后缀自动机 (我不会啊) 那这道题只能用后缀数组了 先把原串倒一下 后缀->前缀 相当于每回在前面加了一个字母 求不同的子串个数 首先 正常的求子 ...