Time Limit: 30000/15000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 793 Accepted Submission(s): 253
#include <bits/stdc++.h> using namespace std ; const int N = 15 ; const int M = 30007 ; const int MAXN = 1000010; const int mod = 1e9+7; int n , m , K ; int maze[N][N] ; int code[N] ; int ch[N] , num ; int ex , ey ; struct HASHMAP { int head[M] , next[MAXN] , tot ; long long st[MAXN] , f[MAXN] ; void init() { memset( head , -1 , sizeof head ) ; tot = 0 ; } void push( long long state , long long ans ) { int u = state % M ; for( int i = head[u] ; ~i ; i = next[i] ) { if( st[i] == state ) { f[i] += ans ; f[i] %= mod ; return ; } } st[tot] = state ; f[tot] = ans % mod ; next[tot] = head[u] ; head[u] = tot++ ; } } mp[2] ; void decode ( int* code , int m , long long st ) { num = st & 63 ; st >>= 6 ; for( int i = m ; i >= 0 ; --i ) { code[i] = st&7 ; st >>= 3 ; } } long long encode( int *code , int m ) { int cnt = 1 ; long long st = 0 ; memset( ch , -1 , sizeof ch) ; ch[0] = 0 ; for( int i = 0 ; i <= m ; ++i ) { if( ch[code[i]] == -1 ) ch[ code[i] ] = cnt++ ; code[i] = ch[ code[i] ] ; st <<= 3 ; st |= code[i] ; } st <<= 6 ; st |= num ; return st ; } void shift( int *code , int m ) { for( int i = m ; i > 0 ; --i ) { code[i] = code[i-1] ; } code[0] = 0 ; } void dpblank( int i , int j , int cur ) { int left , up ; for( int k = 0 ; k < mp[cur].tot ; ++k ) { decode( code , m , mp[cur].st[k] ); left = code[j-1] ; up = code[j] ; if( left && up ) { if( left == up ) { if( num >= K ) continue ; int c = 0 ; for( int y = 0 ; y < j - 1 ; ++y ) if( code[y] ) c++ ; if( c&1 ) continue ; num++ ; code[j-1] = code[j] = 0 ; if( j == m ) shift( code , m ) ; mp[cur^1].push( encode(code,m),mp[cur].f[k] ); }else { code[j-1] = code[j] = 0 ; for( int t = 0 ; t <= m ; ++t ) { if( code[t] == up ) code[t] = left ; } if( j == m ) shift( code,m ); mp[cur^1].push(encode(code,m),mp[cur].f[k]) ; } } else if( ( left && ( !up ) ) || ( up && (!left ) ) ) { int t ; if( left ) t = left ; else t = up ; if( maze[i][j+1] ) { code[j-1] = 0 ; code[j] = t ; mp[cur^1].push( encode(code,m) , mp[cur].f[k] ) ; } if( maze[i+1][j] ) { code[j-1] = t ; code[j] = 0 ; if( j == m ) shift( code , m ); mp[cur^1].push(encode(code,m),mp[cur].f[k]); } } else { if( maze[i][j+1] && maze[i+1][j] ) { code[j-1] = code[j] = 13 ; mp[cur^1].push( encode(code,m),mp[cur].f[k]); } } } } void dpblock( int i , int j , int cur ) { for( int k = 0 ; k < mp[cur].tot ; ++k ) { decode( code , m , mp[cur].st[k] ); code[j-1] = code[j] = 0 ; if( j == m ) shift( code , m ); mp[cur^1].push( encode(code,m) , mp[cur].f[k] ); } } void Solve() { int v = 0 ; mp[v].init(); mp[v].push(0,1); for( int i = 1 ; i <= n ; ++i ) { for( int j = 1 ; j <= m ; ++j ) { mp[v^1].init() ; if( maze[i][j] ) dpblank( i , j , v ) ; else dpblock( i , j , v ); v ^= 1 ; } } long long ans = 0 ; for( int i = 0 ; i < mp[v].tot ; ++i ) { if( mp[v].st[i] == K ) ans = ( ans + mp[v].f[i] ) % mod ; } cout << ans << endl ; } string s ; int main () { // freopen("in.txt","r",stdin); ios::sync_with_stdio(0); int _ ; cin >> _ ; while( _-- ) { cin >> n >> m >> K ; ex = 0 ; memset( maze , 0 , sizeof maze ) ; for( int i = 1 ; i <= n ; ++i ) { cin >> s ; for( int j = 0 ; j < m ; ++j ) { if( s[j] == ‘.‘ ) { ex = i , ey = j + 1 ; maze[i][j+1] = 1 ; } } } if( !ex ) { cout << ‘0‘ << endl ; continue ; } else Solve(); } return 0 ; }
HDU 4285 circuits( 插头dp , k回路 )
原文:http://www.cnblogs.com/hlmark/p/4371353.html