ural 1519 插头DP 入门

来源:互联网 发布:java的保留字有哪些 编辑:程序博客网 时间:2024/05/14 14:04

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

#include<stdio.h>#include<string.h>#include<iostream>#define LL long long#define LMTh 1997000using 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;}


原创粉丝点击