zoukankan      html  css  js  c++  java
  • 插头dp模板

    P5056 【模板】插头dp

    题目背景

    ural 1519

    陈丹琦《基于连通性状态压缩的动态规划问题》中的例题

    题目描述

    给出(n*m)的方格,有些格子不能铺线,其它格子必须铺,形成一个闭合回路。问有多少种铺法?

    输入输出格式

    输入格式:

    (1)行,(n,m(2le n,mle 12))

    从第(2)行到第(n+1)行,每行一段字符串((m)个字符),*表不能铺线,.表必须铺

    输出格式:

    输出一个整数,表示总方案数


    插头(DP)模板

    几个关键字:Hash挂链,讨论,自己画图

    几个细节:挂链别挂错了,好好讨论,有些地方判是为了剪枝,代码风格

    几个质数:590027,299989,299987

    (color{pink}{link})


    Code:

    #include <cstdio>
    #include <cstring>
    #define ll long long
    const int N=3e5+10;
    const int mod=299989;
    int head[N],Next[N],to[N],sta[2][N],cnt[2],tot;
    int n,m,ma[15][15],cur,bit[26],endx,endy;
    ll dp[2][N],ans;
    void Ins(int s,ll val)
    {
        int x=s%mod;
        for(int i=head[x];i;i=Next[i])
            if(sta[cur][to[i]]==s)
            {
                dp[cur][i]+=val;
                return;
            }
        dp[cur][++cnt[cur]]=val;
        sta[cur][cnt[cur]]=s;
        to[++tot]=cnt[cur];
        Next[tot]=head[x];
        head[x]=tot;
    }
    void DP()
    {
        dp[cur][++cnt[cur]]=1,sta[cur][cnt[cur]]=0;
        for(int i=1;i<=n;i++)
        {
            for(int s=1;s<=cnt[cur];s++) sta[cur][s]<<=2;
            for(int j=1;j<=m;j++)
            {
                cur^=1;
                tot=cnt[cur]=0;
                memset(head,0,sizeof(head));
                for(int s=1;s<=cnt[cur^1];s++)
                {
                    int lassta=sta[cur^1][s];ll lasans=dp[cur^1][s];
                    int sd=(lassta>>bit[j])&3,sr=(lassta>>bit[j-1])&3;
                    if(!ma[i][j])
                    {
                        if(!sd&&!sr)
                            Ins(lassta,lasans);
                    }
                    else if(!sd&&!sr)
                    {
                        if(ma[i+1][j]&&ma[i][j+1])
                            Ins(lassta+(1<<bit[j-1])+(1<<bit[j]+1),lasans);
                    }
                    else if(!sd&&sr)
                    {
                        if(ma[i][j+1])//右
                            Ins(lassta+(sr<<bit[j])-(sr<<bit[j-1]),lasans);
                        if(ma[i+1][j])//下
                            Ins(lassta,lasans);
                    }
                    else if(sd&&!sr)
                    {
                        if(ma[i][j+1])
                            Ins(lassta,lasans);
                        if(ma[i+1][j])
                            Ins(lassta+(sd<<bit[j-1])-(sd<<bit[j]),lasans);
                    }
                    else if(sr==1&&sd==1)
                    {
                        int ct=1;
                        for(int k=j+2;k<=m+1;k++)
                        {
                            if(((lassta>>bit[k-1])&3)==1) ++ct;
                            if(((lassta>>bit[k-1])&3)==2) --ct;
                            if(!ct)
                            {
                                Ins(lassta-(sr<<bit[j-1])-(sd<<bit[j])-(1<<bit[k-1]),lasans);
                                break;
                            }
                        }
                    }
                    else if(sr==2&&sd==2)
                    {
                        int ct=1;
                        for(int k=j-1;k;k--)
                        {
                            if(((lassta>>bit[k-1])&3)==1) --ct;
                            if(((lassta>>bit[k-1])&3)==2) ++ct;
                            if(!ct)
                            {
                                Ins(lassta-(sr<<bit[j-1])-(sd<<bit[j])+(1<<bit[k-1]),lasans);
                                break;
                            }
                        }
                    }
                    else if(sr==2&&sd==1)
                        Ins(lassta-(sr<<bit[j-1])-(sd<<bit[j]),lasans);
                    else if(i==endx&&j==endy)
                        ans+=lasans;
                }
            }
        }
    }
    int main()
    {
        scanf("%d%d",&n,&m);
        for(int i=1;i<=25;i++) bit[i]=i<<1;
        for(int i=1;i<=n;i++)
        {
            scanf("
    ");
            for(int j=1;j<=m;j++)
            {
                char c;
                scanf("%c",&c);
                if(c=='.')
                    ma[i][j]=1,endx=i,endy=j;
            }
        }
        DP();
        printf("%lld
    ",ans);
        return 0;
    }
    

    2018.12.20

  • 相关阅读:
    使用javaDate类代数据仓库维度表
    Hermes和开源Solr、ElasticSearch 不同
    MapReduce 异常 LongWritable cannot be cast to Text
    吐槽CSDN编辑
    Codeforces 452A Eevee
    看不清楚未来,请做好如今
    JDBC数据库连接
    mixpanel实验教程(2)
    使用jquery+一般处理程序异步载入信息
    Eclipse中的Maven项目报Unbound classpath variable错误
  • 原文地址:https://www.cnblogs.com/butterflydew/p/10150605.html
Copyright © 2011-2022 走看看