ural 1519 插头DP 入门

总体上参考ccy,不说了,上代码

#include<stdio.h>
#include<string.h>
#include<iostream>
#define LL long long
#define LMTh 1997000
using namespace std;
int a[15][15],jz[15],total[2];
LL sum[2][200000];
LL state[2][200000];
int Hash[LMTh];
int n,m,nn,mm,k;
inline int cango(int i,int j)
{
   if(i>n||j>m||i<=0||j<=0)return 0;
    if(0==a[i][j])return 0;
    return 1;
}
void mov(void)
{
    int i;
    jz[0]=0;
    for(i=1;i<=14;i++)
    jz[i]=i<<1;
}
void hash_in(LL s,LL data)
{
    int hashpos=s%LMTh;
    while(Hash[hashpos])
    {
        if(state[k][Hash[hashpos]]==s)
        {
            sum[k][Hash[hashpos]]+=data;
            return;
        }
        hashpos=(hashpos+1)%LMTh;//刚多加了个“+”
    }
    total[k]++;
    Hash[hashpos]=total[k];
    state[k][total[k]]=s;sum[k][total[k]]=data;
}
LL work(void)
{
    LL ans=0;k=0;
    int i,j,u,v;
        memset(Hash,0,sizeof(Hash));
        memset(sum[k],0,sizeof(sum[k]));
        memset(state[k],0,sizeof(state[k]));
        total[k]=0;
        hash_in(0,1);
    for( i=1;i<=n;i++)
    {
        for( j=1;j<=m;j++)
        {
                            k^=1;
                memset(Hash,0,sizeof(Hash));
                memset(sum[k],0,sizeof(sum[k]));
                memset(state[k],0,sizeof(state[k]));
                total[k]=0;
            for( u=1;u<=total[1-k];u++)
            {
                LL s=state[1-k][u];
                LL data=sum[1-k][u];
                int p=(s>>jz[j-1])%4;
                int q=(s>>(jz[j]))%4;
                if(0==a[i][j])
                {
                    if(p==0&&q==0)
                      hash_in(s,data);
                }
                else
                {
                    if(p==0&&q==0)
                    {
                       if(cango(i,j+1)&&cango(i+1,j))
                       {
                        LL temp=s+(1<<jz[j-1])+(2<<jz[j]);
                        hash_in(temp,data);
                       }
                        continue;
                    }
                    if(p==0&&q>0)
                    {
                        if(cango(i,j+1))
                          hash_in(s,data);
                        if(cango(i+1,j))//这里居然会漏
                        {
                            LL temp=s-(q<<jz[j]);
                            temp+=(q<<jz[j-1]);
                            hash_in(temp,data);
                        }
                        continue;
                    }
                    if(p>0&&q==0)
                    {
                        if(cango(i+1,j))
                          hash_in(s,data);
                        if(cango(i,j+1))
                        {
                            LL temp=s-(p<<jz[j-1]);
                            temp+=p<<jz[j];
                            hash_in(temp,data);
                        }
                        continue;
                    }
                    if(p==1&&q==1)
                    {
                        int bra=1;
                        LL temp;
                        for( v=j+1;v<=m;v++)
                        {
                            int w=(s>>jz[v])%4;
                            if(w==1)bra++;
                            else if(w==2)bra--;
                            if(bra==0)
                            {
                               temp=s-(1<<jz[v]);
                               break;
                            }
                        }
                        temp-=(1<<jz[j-1])+(1<<jz[j]);
                        hash_in(temp,data);
                        continue;
                    }
                    if(p==2&&q==2)
                    {
                        int bra=1;
                        LL temp;
                        for(int v=j-2;v>0;v--)
                        {
                            int w=(s>>jz[v])%4;
                            if(w==2)bra++;
                            if(w==1)bra--;
                            if(bra==0)
                            {
                                temp=s+(1<<jz[v]);
                                break;
                            }
                        }
                        temp-=(2<<jz[j])+(2<<jz[j-1]);
                        hash_in(temp,data);
                        continue;
                    }
                    if(p==2&&q==1)
                    {
                        LL temp=s-(p<<jz[j-1])-(q<<jz[j]);
                        hash_in(temp,data);
                        continue;
                    }
                    if(p==1&&q==2&&i==nn&&j==mm)
                     ans+=data;
                }
            }
        }
        for(int i=1;i<=total[k];i++)
        state[k][i]=state[k][i]<<2;
    }
    return ans;
}
int main()
{
      mov();
      int i,j;
      char str[16];
        scanf("%d%d",&n,&m);getchar();
        memset(a,0,sizeof(a));
        for( i=1;i<=n;i++)
        {
            scanf("%s",&str[1]);
            for(j=1;str[j];j++)
            if(str[j]=='.')
            {
                a[i][j]=1;
                nn=i;
                mm=j;
            }
            else if(str[j]=='*')a[i][j]=0;
        }
        cout<<work()<<endl;//听说要改成这样
    return 0;
}


你可能感兴趣的:(ural 1519 插头DP 入门)