只是换了一种方法来表示方法 但是括号表示好像跑得快些
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<iostream>
#include<queue>
#define SF scanf
#define PF printf
#define bit(x) (1<<(x))
#define getbit(x, y) (((x) >> mov[y]) & 3)
#define BIT(x, y) ((x) << mov[y])
#define clrbit(x, i, j) ((x) & (~(3 << mov[i])) & (~(3 << mov[j])))
using namespace std;
typedef long long LL;
const int MAXN = 13;
const int MAXS = 1 << 12;
const int MOD = (1<<15) - 1;
const int MAXNODE = 1000000;
const int mov[20]={0, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28};
struct Hash {
int sz, adj[MOD+10], next[MOD+10];
int sta[MAXNODE+10];
LL val[MAXNODE+10];
void clr() {
memset(adj, -1, sizeof(adj));
for(int i = 0; i < sz; i++) val[i] = 0;
sz = 0;
}
void push(int s, LL v) {
int ss = s & MOD;
for(int i = adj[ss]; ~i; i = next[i])
if(sta[i] == s) {
val[i] += v; return ;
}
val[sz] = v; sta[sz] = s; next[sz] = adj[ss]; adj[ss] = sz++;
}
} dp[2];
int n, m, M[MAXN+10][MAXN+10], ex, ey, cur;
int FindL(int st, int x) {
int cnt = 1;
for(int i = x-1; i >= 0; i--) {
int s = ((st >> mov[i]) & 3);
if(s == 2) cnt++;
else if(s == 1) cnt--;
if(!cnt) return i;
}
return -1;
}
int FindR(int st, int x) {
int cnt = 1;
for(int i = x+1; i <= m; i++) {
int s = ((st >> mov[i]) & 3);
if(s == 1) cnt++;
else if(s == 2) cnt--;
if(!cnt) return i;
}
return -1;
}
LL solve() {
cur = 0; dp[0].clr(); dp[0].push(0, 1);
for(int i = 1; i <= n; i++) {
cur ^= 1;
dp[cur].clr();
for(int j = 0; j < dp[cur^1].sz; j++) {
dp[cur].push(dp[cur^1].sta[j] << 2, dp[cur^1].val[j]);
}
for(int j = 1; j <= m; j++) {
cur ^= 1; dp[cur].clr();
for(int k = 0; k < dp[cur^1].sz; k++) {
int L = getbit(dp[cur^1].sta[k], j-1);
int U = getbit(dp[cur^1].sta[k], j);
int s = clrbit(dp[cur^1].sta[k], j-1, j);
//PF("* %d %d %d\n", L, U, s);
if(!L && !U) {
if(!M[i][j]) dp[cur].push(s, dp[cur^1].val[k]);
else if(i < n && j < m && M[i+1][j] && M[i][j+1])
dp[cur].push(s|BIT(1, j-1)|BIT(2, j), dp[cur^1].val[k]);
}
else if(!L || !U) {
int dir = L ? L : U;
if(i < n && M[i+1][j]) dp[cur].push(s|BIT(dir, j-1), dp[cur^1].val[k]);
if(j < m && M[i][j+1]) dp[cur].push(s|BIT(dir, j), dp[cur^1].val[k]);
}
else if(L == 1 && U == 1)
dp[cur].push(s^BIT(3, FindR(s, j)), dp[cur^1].val[k]);
else if(L == 2 && U == 2)
dp[cur].push(s^BIT(3, FindL(s, j-1)), dp[cur^1].val[k]);
else if(L == 2 && U == 1)
dp[cur].push(s, dp[cur^1].val[k]);
else if(i == ex && j == ey)
dp[cur].push(s, dp[cur^1].val[k]);
}
}
}
for(int i = 0; i < dp[cur].sz; i++)
if(!dp[cur].sta[i]) return dp[cur].val[i];
return 0;
}
int main() {
char ch;
SF("%d%d", &n, &m);
for(int i = 1; i <= n; i++)
for(int j = 1; j <= m; j++) {
SF(" %c", &ch);
if(ch == '*') M[i][j] = 0;
else M[i][j] = 1, ex = i, ey = j;
}
LL ans = solve();
cout << ans;
}