• P5056 【模板】插头dp


    传送门

    完了……好像……已经把插头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
    ",ans);
        }
    }T;
    int main(){return 0;}
    
  • 相关阅读:
    java输出菱型
    java----内部类
    java中的多重继承
    java算法--三个数字比较大小
    Python基础(2)
    Python基础(1)
    Redis主从同步
    一种高效的进程间的通信方式
    自旋锁和互斥锁的区别
    Linux读写锁的使用
  • 原文地址:https://www.cnblogs.com/bztMinamoto/p/10066157.html
Copyright © 2020-2023  润新知