• P5056 【模板】插头dp


    传送门

    这是一个模板,如果明白插头 $dp$ 的原理,大力分类讨论就完事了

    注意一些细节,比如统计答案时不一定是在 $n,m$ ,因为 $n,m$ 可能不能放

    自认为自己的代码比较好看...

    #include<iostream>
    #include<cstdio>
    #include<algorithm>
    #include<cstring>
    #include<cmath>
    using namespace std;
    typedef long long ll;
    inline int read()
    {
        int x=0,f=1; char ch=getchar();
        while(ch<'0'||ch>'9') { if(ch=='-') f=-1; ch=getchar(); }
        while(ch>='0'&&ch<='9') { x=(x<<1)+(x<<3)+(ch^48); ch=getchar(); }
        return x*f;
    }
    const int N=2e5,M=2e6;
    int n,m,a[17][17],bit[27],cur,pre,lstx,lsty;
    ll f[2][M],Ans;
    int fir[N+7],from[M+7],to[2][M+7],cntt[2];
    inline void insert(int sta,ll val)
    {
        int p=sta%N;
        for(int i=fir[p];i;i=from[i])
            if(to[cur][i]==sta) { f[cur][i]+=val; return; }
        from[++cntt[cur]]=fir[p]; fir[p]=cntt[cur];
        to[cur][cntt[cur]]=sta; f[cur][cntt[cur]]=val;
    }
    void DP()
    {
        f[cur][1]=cntt[cur]=1; int now,right,down; ll val;
        for(int i=1;i<=n;i++)
        {
            for(int j=1;j<=cntt[cur];j++) to[cur][j]<<=2;
            for(int j=1;j<=m;j++)
            {
                pre=cur; cur^=1; cntt[cur]=0; memset(fir,0,sizeof(fir));
                for(int k=1;k<=cntt[pre];k++)
                {
                    now=to[pre][k]; val=f[pre][k];
                    right=(now>>bit[j-1])%4; down=(now>>bit[j])%4;
                    if(a[i][j]) { if(!right&&!down) insert(now,val); continue; }
                    if(!right&&!down)
                        if(j!=m) insert(now+(1<<bit[j-1])+((1<<bit[j])<<1),val);
                    if(right&&!down)
                    {
                        insert(now,val);
                        if(j!=m) insert(now-right*(1<<bit[j-1])+right*(1<<bit[j]),val);
                    }
                    if(!right&&down)
                    {
                        insert(now-down*(1<<bit[j])+down*(1<<bit[j-1]),val);
                        if(j!=m) insert(now,val);
                    }
                    if(right==1&&down==1)
                    {
                        int cnt=1;
                        for(int l=j+1;l<=m;l++)
                        {
                            if((now>>bit[l])%4==1) cnt++;
                            if((now>>bit[l])%4==2) cnt--;
                            if(!cnt)
                            {
                                insert(now-(1<<bit[j-1])-(1<<bit[j])-(1<<bit[l]),val);
                                break;
                            }
                        }
                    }
                    if(right==2&&down==2)
                    {
                        int cnt=1;
                        for(int l=j-2;l>=0;l--)
                        {
                            if((now>>bit[l])%4==1) cnt--;
                            if((now>>bit[l])%4==2) cnt++;
                            if(!cnt)
                            {
                                insert(now-((1<<bit[j-1])<<1)-((1<<bit[j])<<1)+(1<<bit[l]),val);
                                break;
                            }
                        }
                    }
                    if(right==2&&down==1)
                        insert(now-((1<<bit[j-1])<<1)-(1<<bit[j]),val);
                    if(right==1&&down==2)
                        if(now==(1<<bit[j-1])+((1<<bit[j])<<1))
                            if(i==lstx&&j==lsty) Ans+=val;
                }
            }
        }
    }
    int main()
    {
        for(int i=1;i<=26;i++) bit[i]=(i<<1);
        n=read(),m=read(); char s[17];
        for(int i=1;i<=n;i++)
        {
            scanf("%s",s+1);
            for(int j=1;j<=m;j++) a[i][j]=(s[j]=='*');
        }
        for(lstx=n;lstx;lstx--)
        {
            bool flag=0;
            for(lsty=m;lsty;lsty--)
                if(!a[lstx][lsty]) { flag=1; break; }
            if(flag) break;
        }
        DP();
        printf("%lld
    ",Ans);
        return 0;
    }
  • 相关阅读:
    composer 安装laravel
    面向对象
    dedecms常用标签
    Illegal modifier for parameter *** , only final is permitted”
    import static和import的区别
    <<Effective Java>> 第四十三条
    java valueOf
    linux的shell编程
    DFA和NFA的区别
    发现一个正则网
  • 原文地址:https://www.cnblogs.com/LLTYYC/p/11464754.html
Copyright © 2020-2023  润新知