poj 1739 插头DP

来源:互联网 发布:科比历届季后赛数据 编辑:程序博客网 时间:2024/06/08 13:50

和上一题很像,只需要增加两行就行。。。

还有hash要开小一点。。。。不然会TLE

AC代码如下:

#include <iostream>#include <cstring>#include <cstdio>#include <algorithm>#include <map>using namespace std;const long long digit[15] = { 1, 3, 9, 27, 81, 243, 729, 2187, 6561, 19683, 59049, 177147, 531441, 1594323, 4782969 };char maps[13][13];long long N, M;//////////////////////////////////////////////////////   哈希表#define LL long longconst int mod = 10007;struct HASH{    int head[mod+10], E, next[80000];    LL val[10000], cnt[10000];    void init() {        memset(head, -1, sizeof(head));        E = 0;    }    int findhash(LL x) {        return (x%mod + mod)%mod;    }    void add(LL x, LL sum) {        int u = findhash(x);        for(int i = head[u];i != -1;i = next[i]) if(val[i] == x) {            cnt[i] += sum;            return ;        }        val[E] = x;        cnt[E] = sum;        next[E] = head[u];        head[u] = E++;    }}biao1, biao2;//////////////////////////////////void init(){memset( maps, 0, sizeof( maps ) );    for( int i = 1; i <= N; i++ ){        scanf( "%s", &maps[i][1] );    }for( int j = 2; j <= M - 1; j++ ){maps[N+1][j] = '#';}maps[N+1][1] = maps[N+1][M] = '.';for( int j = 1; j <= M; j++ ){maps[N+2][j] = '.';}N += 2;}long long solve(){    int lasti, lastj;long long ans;long long code[13];    lasti = -1;    lastj = -1;    int flag = 0;    for( int i = N; i >= 1 && !flag; i-- ){        for( int j = M; j >= 1 && !flag; j-- ){            if( maps[i][j] == '.' ){                lasti = i;                lastj = j;                flag = 1;                break;            }        }    }if( lasti == -1 ){return 0;}biao1.init();biao2.init();biao2.add( 0, 1 );ans = 0;    for( int i = 1; i <= N; i++ ){biao1.init();for( int k = 0; k < biao2.E; k++ ){long long tid, tsum;tid = biao2.val[k];tsum = biao2.cnt[k];biao1.add( tid * 3, tsum );}for( int j = 0; j < M; j++ ){biao2.init();for( int k = 0; k < biao1.E; k++ ){long long tid, tsum;tid = biao1.val[k];tsum = biao1.cnt[k];long long numj, numj1;numj = ( tid % digit[j+1] ) / digit[j];numj1 = ( tid % digit[j+2] ) / digit[j+1];if( maps[i][j+1] == '.' ){if( numj == 0 && numj1 == 0 ){long long tt = tid - digit[j] * numj - digit[j+1] * numj1 + digit[j] * 1 + digit[j+1] * 2;if( j + 1 < M ) biao2.add( tt, tsum );}else if( numj == 0 || numj1 == 0 ){    int temp = numj + numj1;long long tt = tid + digit[j] * temp - digit[j] * numj - digit[j+1] * numj1;biao2.add( tt, tsum );    tt = tid - digit[j] * numj - digit[j+1] * numj1 + digit[j+1] * temp;    if( j + 1 < M ) biao2.add( tt, tsum );}else{    if( numj == 1 && numj1 == 1 ){        int temp = 0;int l;        for( l = j + 2; l <= M; l++ ){long long ttt = tid % digit[l+1] / digit[l];if( ttt == 2 ){                if( temp == 0 ){                    break;                }else{                    temp--;                }            }else if( ttt == 1 ){                temp++;            }        }if( l <= M ){long long ttt = tid % digit[l+1] / digit[l];long long tt = tid - digit[j] * numj - digit[j+1] * numj1 + digit[l] * ( 1 - ttt );biao2.add( tt, tsum );}    }else if( numj == 2 && numj1 == 2 ){        int temp = 0;int l;        for( l = j - 1; l >= 0; l-- ){int ttt = tid % digit[l+1] / digit[l];            if( ttt == 1 ){                if( temp == 0 ){                    break;                }else{                    temp--;                }            }else if( ttt == 2 ){                temp++;            }        }if( l >= 0 ){long long ttt = tid % digit[l+1] / digit[l];long long tt = tid - digit[j] * numj - digit[j+1] * numj1 + digit[l] * ( 2 - ttt );biao2.add( tt, tsum );}    }else if( numj == 1 && numj1 == 2 ){        long long tt = tid - digit[j] * numj - digit[j+1] * numj1;        if( i == lasti && j + 1 == lastj && !tt ){            biao2.add( tt, tsum );ans += tsum;        }    }else{long long tt = tid - digit[j] * numj - digit[j+1] * numj1;biao2.add( tt, tsum );    }}}else{if( numj == 0 && numj1 == 0 ){biao2.add( tid, tsum );}}            }biao1 = biao2;        }    }    return ans;}int main(){    while( cin >> N >> M && !( N == 0 && M == 0 ) ){        init();        printf( "%lld\n", solve() );    }    return 0;}


0 0
原创粉丝点击