码迷,mamicode.com
首页 > 其他好文 > 详细

P5056 【模板】插头dp

时间:2018-12-04 20:08:19      阅读:147      评论:0      收藏:0      [点我收藏+]

标签:namespace   www   scanf   插头dp   show   ons   register   com   %s   

传送门

完了……好像……已经把插头dp全都忘光了……
可以去看看这篇blog
为了卡常变得丧心病狂的代码

//minamoto
#include<bits/stdc++.h>
#define ll long long
#define R register
#define fp(i,a,b) for(R int i=a,I=b+1;i<I;++i)
#define fd(i,a,b) for(R int i=a,I=b-1;i>I;--i)
#define go(u) for(int i=head[u],v=e[i].v;i;i=e[i].nx,v=e[i].v)
using namespace std;
const int N=25,P=23333,M=40005;
struct MAIN{
    int n,m;char s[N];bool mp[N][N];
    int cnt[2],cur,vis[2][M],hsh[P+5],ex,ey,S,l,r,dt,val;
    ll dp[2][M],ans;
    void insert(R int S,R ll sum){
        R int pos=S%P;
        while(hsh[pos]){
            if(vis[cur][hsh[pos]]==S)return (void)(dp[cur][hsh[pos]]+=sum);
            pos=(pos+1)%P;
        }hsh[pos]=++cnt[cur],vis[cur][hsh[pos]]=S,dp[cur][hsh[pos]]=sum;
    }
    MAIN(){
        scanf("%d%d",&n,&m);
        fp(i,1,n){
            scanf("%s",s+1);
            fp(j,1,m)if(s[j]=='.')mp[i][j]=1,ex=i,ey=j;
        }
        dp[0][1]=cnt[0]=1;
        fp(i,1,n){
            fp(j,1,m){
                cnt[cur^=1]=0;memset(hsh,0,sizeof(hsh));
                fp(k,1,cnt[cur^1]){
                    S=vis[cur^1][k],l=(S>>((j-1)<<1))&3,r=(S>>(j<<1))&3;
                    if(!mp[i][j]){if(!l&&!r)insert(S,dp[cur^1][k]);continue;}
                    if(!l&&!r){
                        if(!mp[i][j+1]||!mp[i+1][j])continue;
                        insert(S^(1<<((j-1)<<1))^(2<<(j<<1)),dp[cur^1][k]);
                    }if(l&&!r){
                        if(mp[i][j+1])insert(S^(l<<((j-1)<<1))^(l<<(j<<1)),dp[cur^1][k]);
                        if(mp[i+1][j])insert(S,dp[cur^1][k]);
                    }if(!l&&r){
                        if(mp[i+1][j])insert(S^(r<<(j<<1))^(r<<((j-1)<<1)),dp[cur^1][k]);
                        if(mp[i][j+1])insert(S,dp[cur^1][k]);
                    }if(l==1&&r==1){
                        dt=1;
                        fp(p,j+1,m){
                            val=(S>>(p<<1))&3;
                            if(val==1)++dt;if(val==2)--dt;
                            if(!dt){S^=(2<<(p<<1))^(1<<(p<<1));break;}
                        }insert(S^(1<<((j-1)<<1))^(1<<(j<<1)),dp[cur^1][k]);
                    }if(l==2&&r==2){
                        dt=1;
                        fd(p,j-2,0){
                            val=(S>>(p<<1))&3;
                            if(val==1)--dt;if(val==2)++dt;
                            if(!dt){S^=(1<<(p<<1))^(2<<(p<<1));break;}
                        }insert(S^(2<<((j-1)<<1))^(2<<(j<<1)),dp[cur^1][k]);
                    }if(l==2&&r==1)insert(S^(2<<((j-1)<<1))^(1<<(j<<1)),dp[cur^1][k]);
                    if(l==1&&r==2&&i==ex&&j==ey)ans+=dp[cur^1][k];
                }
            }
            fp(j,1,cnt[cur])vis[cur][j]<<=2;
        }
        printf("%lld\n",ans);
    }
}T;
int main(){return 0;}

P5056 【模板】插头dp

标签:namespace   www   scanf   插头dp   show   ons   register   com   %s   

原文地址:https://www.cnblogs.com/bztMinamoto/p/10066157.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!