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. JQ淡入淡出效果

    <script type="text/javascript"> //页面淡入淡出 $(document).ready(function() { $('body').hi ...

  2. [Papers] Semantic Segmentation Papers(1)

    目录 FCN Abstract Introduction Related Work FCN Adapting classifiers for dense prediction Shift-and-st ...

  3. 【codeforces 723E】One-Way Reform

    [题目链接]:http://codeforces.com/contest/723/problem/E [题意] 给你一个无向图; 让你把这m条边改成有向图; 然后使得出度数目等于入度数目的点的数目最多 ...

  4. SpringMVC-HandlerMapping和HandlerAdapter

    网上介绍HandlerMapping和HandlerAdapter的文章很多,今天我用自己的理解和语言来介绍下HandlerMapping和HandlerAdapter 一. HandlerMappi ...

  5. java的数组index[]方括号内是可以进行算数运算的

    java的数组index[]方括号内饰可以进行算数运算的 如: String[] stringArray = testString.split("\\."); System.out ...

  6. Visual C++ 经常使用快捷键

    大写和小写 Ctrl+Shift+U: 所有变为大写 Ctrl+U: 所有变为小写 凝视 Ctrl+K+Crtr+C: 凝视选定内容  Ctrl+K+Crtr+U: 取消选定凝视内容 折叠 折叠代码: ...

  7. C语言实现使用动态数组实现循环队列

    我在上一篇博客<C语言实现使用静态数组实现循环队列>中实现了使用静态数组来模拟队列的操作. 因为数组的大小已经被指定.无法动态的扩展. 所以在这篇博客中,我换成动态数组来实现. 动态数组能 ...

  8. linux虚拟机网络设置好ping百度没有用

    场景:公司内网,本机使用的是本地连接,不是wiff,虚拟机设置了桥接模式 问题:使用桥接模式 启动好网络服务,查看ifconfig也获取到了设置的ip,可是ping了www.baidu.com还是没有 ...

  9. 【POJ 3273】 Monthly Expense (二分)

    [POJ 3273] Monthly Expense (二分) 一个农民有块地 他列了个计划表 每天要花多少钱管理 但他想用m个月来管理 就想把这个计划表切割成m个月来完毕 想知道每一个月最少花费多少 ...

  10. jdk7与jdk8环境共存与切换

    1,先安装jdk7,配置环境变量JAVA_HOME,然后安装jdk8. 2,安装jdk8后,JAVA_HOME指向未做修改,执行java -version显示还是以前的jdk7版本信息, 3,接下来我 ...