[ural1519]Formula 1 && 插头DP
2015-04-11 17:18
477 查看
这里用的是最小整数表示法 具体方法参考cdq论文- -
if(U)里面多打了个else引发了一场腥风血雨啊QAQ
if(U)里面多打了个else引发了一场腥风血雨啊QAQ
#include<cstdio> #include<algorithm> #include<cstring> #include<iostream> #include<queue> #define SF scanf #define PF printf #define bit(x) (1<<(x)) #define update dp[cur].push(encode() >> 3*(j==m) , dp[cur^1].f[k]) using namespace std; typedef long long LL; const int MAXNODE = 1000000; const int MAXN = 12; const int MOD = 233333; struct Hash { int sz, adj[MOD+1], next[MAXNODE+10]; LL state[MAXNODE+10], f[MAXNODE+10]; void clr() { sz = 0; memset(adj, -1, sizeof(adj)); } int push(LL s, LL val) { int u = s % MOD; for(int i = adj[u]; ~i; i = next[i]) if(state[i] == s) return f[i] += val; state[sz] = s; f[sz] = val; next[sz] = adj[u]; adj[u] = sz++; return f[sz-1]; } } dp[2]; int n, m, M[MAXN+10][MAXN+10], ex, ey, cur; int a[MAXN+10], num[MAXN+10]; void decode(LL s) { for(int i = m; i >= 0; i--) a[i] = s & 7, s >>= 3; } LL encode() { memset(num, 0, sizeof(num)); int k = 0; LL ret = 0; for(int i = 0; i <= m; i++) { if(!num[a[i]] && a[i]) num[a[i]] = ++k; ret = (ret << 3) | num[a[i]]; } return ret; } void change(int x, int y) { for(int i = 0; i <= m; i++) if(a[i] == x) a[i] = y; } void dpblank(int i, int j) { for(int k = 0; k < dp[cur^1].sz; k++) { decode(dp[cur^1].state[k]); int &L = a[j-1], &U = a[j]; if(L && U) { if(L == U) { if(i == ex && j == ey) { L = U = 0; update; } } else { change(L, U); L = U = 0; update; } } else if(L) { if(M[i+1][j]) dp[cur].push(dp[cur^1].state[k] >> 3 * (j==m), dp[cur^1].f[k]); if(M[i][j+1]) { U = L; L = 0; update; } } else if(U) { if(M[i][j+1]) dp[cur].push(dp[cur^1].state[k] >> 3 * (j==m), dp[cur^1].f[k]); if(M[i+1][j]) { L = U; U = 0; update; } } else { if(M[i][j+1] && M[i+1][j]) { L = U = m+1; update; } } } } void dpblock(int i, int j) { for(int k = 0; k < dp[cur^1].sz; k++) dp[cur].push(dp[cur^1].state[k] >> (3 * (j == m)), dp[cur^1].f[k]); } 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[ex = i][ey = j] = 1; else M[i][j] = 0; } dp[0].clr(); dp[0].push(0, 1); for(int i = 1; i <= n; i++) for(int j = 1; j <= m; j++) { cur ^= 1; dp[cur].clr(); if(M[i][j]) dpblank(i, j); else dpblock(i, j); } LL ans = 0; for(int i = 0; i < dp[cur^1].sz; i++) ans += dp[cur^1].f[i]; cout << ans; }
相关文章推荐
- [ural1519]Formula 1 && 插头DP(括号表示法)
- [省选前题目整理][URAL 1519]Formula 1(插头DP)
- [BZOJ]1814 Ural 1519 Formula 1 插头DP
- [URAL1519] Formula 1 [插头dp入门]
- URAL1519 Formula 1(插头dp的基础题 ——详细解释)
- HDU 1693 Eat the Trees(插头DP、棋盘哈密顿回路数)+ URAL 1519 Formula 1(插头DP、棋盘哈密顿单回路数)
- 【URAL 1519】【插头dp模板】Formula 1
- 【Ural1519】Formula 1 插头DP模板
- [URAL1519]-Formula 1-插头DP
- bzoj 1814: Ural 1519 Formula 1 插头dp经典题
- 【BZOJ1814】Ural 1519 Formula 1 插头DP
- URAL 1519 Formula 1(插头DP)
- URAL 1519 Formula 1 (插头DP,常规)
- Ural 1519 Formula --插头DP
- ural 1519 Formula 1(插头dp)
- URAL - 1519 Formula 1 (插头DP)
- Ural 1519 Formula 1 插头DP(单回路)
- URAL 1519 Formula 1 插头DP
- Ural 1519 Formula 1 插头DP
- URAL 1519 Formula 1 dp(插头)