zoukankan      html  css  js  c++  java
  • LG P5056 【模板】插头dp

    Descriprion

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

    Solution

    使用括号表示法记录状态,记1为 '(' ,2为 ')' ,0为无插头,分8种情况讨论:

    • 1:当前格子有障碍,此时必须下插头和右插头为0,转移后状态不变
    • 2:当前格子下插头和右插头为0,转移后右插头为1,下插头为2
    • 3:当前格子有右插头,无下插头,转移后右插头位置不变或向右移动一位
    • 4:当前格子有下插头,无右插头,转移后下插头位置不变或向左移动一位
    • 5:当前格子下插头和右插头为1,转移后从当前格子向右首个不匹配的2变为1
    • 6:当前格子下插头和右插头为2,转移后从当前格子向左首个不匹配的1变为2
    • 7:当前格子右插头为2,左插头为1,转移后删除两插头
    • 8:当前格子右插头为1,左插头为2,此时必须为最后一个可访问格子,更新总答案

    优化:使用链表存储状态为模数同余系的状态;滚动数组

    #include<iostream>
    #include<cstring>
    #include<cstdio>
    using namespace std;
    int n,m,map[15][15],endx,endy,bits[15],pre=1,cur,tots[2],state[2][600000],head[600000],tot;
    const int mod=590027;
    long long ans,dp[2][600000];
    struct Edge
    {
        int to,nxt;
    }edge[600000];
    inline int read()
    {
        int f=1,w=0;
        char ch=0;
        while(ch<'0'||ch>'9')
        {
            if(ch=='-')
                f=-1;
            ch=getchar();
        }
        while(ch>='0'&&ch<='9')
        {
            w=(w<<1)+(w<<3)+ch-'0';
            ch=getchar();
        }
        return f*w;
    }
    void insert(int sta,long long val)
    {
        int key=sta%mod;
        for(int i=head[key];i;i=edge[i].nxt)
        {
            if(state[cur][edge[i].to]==sta)
            {
                dp[cur][edge[i].to]+=val;
                return;
            }
        }
        tots[cur]++;
        state[cur][tots[cur]]=sta;
        dp[cur][tots[cur]]=val;
        edge[++tot]=(Edge){tots[cur],head[key]};
        head[key]=tot;
    }
    void DP()
    {
        tots[cur]=1;
        state[cur][1]=0;
        dp[cur][1]=1;
        for(int i=1;i<=n;i++)
        {
            for(int j=1;j<=tots[cur];j++)
            {
                state[cur][j]<<=2;
            }
            for(int j=1;j<=m;j++)
            {
                tot=0;
                memset(head,0,sizeof(head));
                swap(cur,pre);
                tots[cur]=0;
                int nowsta=0,d=0,r=0;
                long long nowans=0;
                for(int k=1;k<=tots[pre];k++)
                {
                    nowsta=state[pre][k];
                    nowans=dp[pre][k];
                    d=(nowsta>>bits[j])%4;
                    r=(nowsta>>bits[j-1])%4;
                    if(!map[i][j])
                    {
                        if(!d&&!r)
                        {
                            insert(nowsta,nowans);
                        }
                    }
                    else if(!d&&!r)
                    {
                        if(map[i+1][j]&&map[i][j+1])
                        {
                            insert(nowsta+(1<<bits[j-1])+2*(1<<bits[j]),nowans);
                        }
                    }
                    else if(!d&&r)
                    {
                        if(map[i+1][j])
                        {
                            insert(nowsta,nowans);
                        }
                        if(map[i][j+1])
                        {
                            insert(nowsta-r*(1<<bits[j-1])+r*(1<<bits[j]),nowans);
                        }
                    }
                    else if(!r&&d)
                    {
                        if(map[i][j+1])
                        {
                            insert(nowsta,nowans);
                        }
                        if(map[i+1][j])
                        {
                            insert(nowsta-d*(1<<bits[j])+d*(1<<bits[j-1]),nowans);
                        }
                    }
                    else if(r==1&&d==1)
                    {
                        int cnt=1;
                        for(int l=j+1;l<=m;l++)
                        {
                            if((nowsta>>bits[l])%4==1)
                            {
                                cnt++;
                            }
                            else if((nowsta>>bits[l])%4==2)
                            {
                                cnt--;
                            }
                            if(!cnt)
                            {
                                insert(nowsta-(1<<bits[j-1])-(1<<bits[j])-(1<<bits[l]),nowans);
                                break;
                            }
                        }
                    }
                    else if(r==2&&d==2)
                    {
                        int cnt=1;
                        for(int l=j-2;l>=0;l--)
                        {
                            if((nowsta>>bits[l])%4==1)
                            {
                                cnt--;
                            }
                            else if((nowsta>>bits[l])%4==2)
                            {
                                cnt++;
                            }
                            if(!cnt)
                            {
                                insert(nowsta-2*(1<<bits[j-1])-2*(1<<bits[j])+(1<<bits[l]),nowans);
                                break;
                            }
                        }
                    }
                    else if(r==2&&d==1)
                    {
                        insert(nowsta-2*(1<<bits[j-1])-(1<<bits[j]),nowans);
                    }
                    else
                    {
                        if(i==endx&&j==endy)
                        {
                            ans+=nowans;
                        }
                    }
                }
            }
        }
    }
    int main()
    {
        n=read();
        m=read();
        for(int i=1;i<=n;i++)
        {
            for(int j=1;j<=m;j++)
            {
                char ch=0;
                while(ch!='.'&&ch!='*')
                {
                    ch=getchar();
                }
                if(ch=='.')
                {
                    map[i][j]=1;
                    endx=i;
                    endy=j;
                }
            }
        }
        for(int i=1;i<=14;i++)
        {
            bits[i]=i<<1;
        }
        DP();
        printf("%lld
    ",ans);
        return 0;
    }
    【模板】插头dp
  • 相关阅读:
    python 的基础 学习 第六天 基础数据类型的操作方法 字典
    python 的基础 学习 第五天 基础数据类型的操作方法
    python 的基础 学习 第四天 基础数据类型
    ASP.NET MVC 入门8、ModelState与数据验证
    ASP.NET MVC 入门7、Hellper与数据的提交与绑定
    ASP.NET MVC 入门6、TempData
    ASP.NET MVC 入门5、View与ViewData
    ASP.NET MVC 入门4、Controller与Action
    ASP.NET MVC 入门3、Routing
    ASP.NET MVC 入门2、项目的目录结构与核心的DLL
  • 原文地址:https://www.cnblogs.com/JDFZ-ZZ/p/13398081.html
Copyright © 2011-2022 走看看