#include <iostream>
#include <cstring>
typedef long long LL;
using namespace std;
const int N = 50000, M = N*2 + 7;
int n, m,end_x,end_y;
int g[20][20], q[2][N], cnt[N];
int h[2][M];
LL v[2][M];
int find(int cur,int x){
int t = x % M;
while(h[cur][t]!=-1&&h[cur][t]!=x)
if(++t==M)
t = 0;
return t;
}
void insert(int cur,int state,LL w){
int t = find(cur, state);
if(h[cur][t]==-1){
h[cur][t] = state, v[cur][t] = w;
q[cur][++cnt[cur]] = t;
}
else
v[cur][t] += w;
}
int get(int state,int k){ //求四進位制第 k 位數字
return state >> k * 2 & 3;
}
int set(int k,int v){ //構造四進位制的第 k 位數字為 v 的數
return v * (1 << k * 2);
}
int main(){
cin >> n >> m;
for(int i = 1; i <= n;i++){
char str[20];
scanf("%s", str + 1);
for (int j = 1; j <= m;j++)
if(str[j]=='.')
g[i][j] = 1, end_x = i, end_y = j;
}
LL res=0;
memset(h, -1, sizeof(h));
int cur = 0;
insert(cur, 0, 1);
for (int i = 1; i <= n;i++){
for (int j = 1; j <= cnt[cur];j++)
h[cur][q[cur][j]] <<= 2;
for (int j = 1; j <= m;j++){
int last = cur;
cur ^= 1, cnt[cur] = 0;
memset(h[cur], -1, sizeof(h[cur]));
for (int k = 1; k <= cnt[last]; k++){
int state = h[last][q[last][k]];
LL w = v[last][q[last][k]];
int x = get(state, j - 1), y = get(state, j);
if(!g[i][j]){
if(!x&&!y)
insert(cur, state, w);
}
else if(!x&&!y){
if(g[i+1][j]&&g[i][j+1])
insert(cur, state + set(j - 1, 1) + set(j, 2), w);
}
else if(!x&&y){
if(g[i][j+1])
insert(cur, state, w);
if(g[i+1][j])
insert(cur, state + set(j - 1, y) - set(j, y), w);
}
else if(x&&!y){
if(g[i][j+1])
insert(cur, state - set(j - 1, x) + set(j, x), w);
if(g[i+1][j])
insert(cur, state, w);
}
else if(x==1&&y==1){
for (int u = j + 1,s = 1;; u++){
int z = get(state, u);
if(z==1)
s++;
else if(z==2){
if(--s==0){
insert(cur,state-set(j-1,x)-set(j,y)-set(u,1),w);
break;
}
}
}
}
else if(x==2&&y==2){
for (int u = j - 2,s=1;;u--){
int z = get(state, u);
if(z==2)
s++;
else if(z==1){
if(--s==0){
insert(cur, state - set(j - 1, x) - set(j, y) + set(u, 1), w);
break;
}
}
}
}
else if(x==2&&y==1){
insert(cur, state - set(j - 1, x) - set(j, y), w);
}
else if(i==end_x&&j==end_y)
res += w;
}
}
}
cout << res << endl;
return 0;
}
【知識】插頭DP
相關文章
- 插頭dp初探
- 插頭DP學習筆記筆記
- 樹形DP二三知識
- BZOJ2655: calc(dp 拉格朗日插值)
- 不帶頭結點的單連結串列的建立(頭插法和尾插法)
- HashMap 連結串列插入方式 → 頭插為何改成尾插 ?HashMap
- CSS零碎知識點(3)——居中頭像CSS
- Java解釋單連結串列中的頭插法以及尾插法Java
- 知識圖譜入門——知識表示與知識建模
- 【知識圖譜】知識圖譜資料構建的“硬骨頭”,阿里工程師如何拿下?深度學習在知識圖譜構建中的應用。阿里工程師深度學習
- 遊戲基礎知識——碼頭場景的設計手法遊戲
- 知識圖譜之知識表示
- 硬碟基本知識(磁軌、扇區、柱面、磁頭數、簇、MBR、DBR)硬碟
- dp 套 dp(dp of dp)小記
- 人工智慧(二、知識表示)——1.知識表示與知識表示的概念人工智慧
- 【知識】Manacher
- 知識點
- 【知識分享】
- linux 知識Linux
- PPT知識
- PHP 知識PHP
- MySQL 知識MySql
- 知識集合
- MySQL知識MySql
- HTTP知識HTTP
- IPsec知識
- Owin知識
- VBA 知識
- Thread知識thread
- 初識python必知的6個知識點Python
- 【實用知識】招投標知識兩則
- Vuejs進階知識(十八)【component 進階知識】VueJS
- DP套DP
- 頭腦王者,輕輕鬆鬆上王者,憑自己的Python知識上王者Python
- 知識圖譜|知識圖譜的典型應用
- 信管知識梳理(三)軟體工程相關知識軟體工程
- IT知識課堂:50道網路基礎知識普及
- 知識圖譜01:知識圖譜的定義