zoukankan      html  css  js  c++  java
  • [bzoj2331][SCOI2011]地板【插头dp】

    【题目链接】
      https://www.lydsy.com/JudgeOnline/problem.php?id=2331
    【题解】
      可以用插头dp的方式表示状态。
      每一位用一个三进制位表示,0表示没有木块向该方向连通,1表示有木块,且还未拐弯。2表示有木块并且拐弯了。
      时间复杂度O(NM22M+2),N>M
      

    /* --------------
        user Vanisher
        problem bzoj-2331 
    ----------------*/
    # include <bits/stdc++.h>
    # define    ll      long long
    # define    inf     0x3f3f3f3f
    # define    P       20110520
    # define    N       110
    # define    T       11
    using namespace std;
    int read(){
        int tmp=0, fh=1; char ch=getchar();
        while (ch<'0'||ch>'9'){if (ch=='-') fh=-1; ch=getchar();}
        while (ch>='0'&&ch<='9'){tmp=tmp*10+ch-'0'; ch=getchar();}
        return tmp*fh;
    }
    vector <int> g[2],f[2];
    int n,m,f1,f2,nex[N],now[N],h[1<<(2*T)],lim;
    char mp[N][N],ne[N][N];
    int getnum(){
        int cnt=0;
        for (int i=0; i<=m; i++) cnt=cnt+(nex[i]<<(i*2));
        return cnt;
    }
    void join(int num){
        int tmp=getnum();
        if (h[tmp]==-1){
            h[tmp]=g[f2].size();
            g[f2].push_back(tmp);
            f[f2].push_back(num);
        }
        else f[f2][h[tmp]]=(f[f2][h[tmp]]+num)%P;
    }
    int main(){
        n=read(), m=read();
        for (int i=0; i<n; i++)
            scanf("
    %s",mp[i]);
        if (n<m){
            for (int i=0; i<n; i++)
                for (int j=0; j<m; j++)
                    ne[j][i]=mp[i][j];
            swap(n,m);
            for (int i=0; i<n; i++)
                for (int j=0; j<m; j++)
                    mp[i][j]=ne[i][j];
        }
        f1=0, f2=1, lim=1<<(2*m+2);
        g[f1].push_back(0); f[f1].push_back(1);
        memset(h,-1,sizeof(h));
        for (int i=0; i<n; i++){
            for (int j=0; j<m; j++){
                for (unsigned k=0; k<g[f1].size(); k++){
                    int tmp=g[f1][k], num=f[f1][k]; 
                    if (tmp>=lim) continue;
                    for (int t=0; t<=m; t++) now[t]=nex[t]=(tmp>>(t*2))&3;
                    if (mp[i][j]=='*'){
                        if (now[j]==0&&now[j+1]==0) join(num);
                    }
                    else {
                        if (now[j]==0&&now[j+1]==0){
                            nex[j]=2, nex[j+1]=2; join(num);
                            nex[j]=1, nex[j+1]=0; join(num);
                            nex[j]=0, nex[j+1]=1; join(num);
                        }
                        if (now[j]!=0&&now[j+1]==0){
                            if (now[j]==1){
                                nex[j]=2, nex[j+1]=0; join(num);
                                nex[j]=0, nex[j+1]=1; join(num);
                            }
                            else {
                                nex[j]=0, nex[j+1]=2; join(num);
                                nex[j]=0, nex[j+1]=0; join(num);
                            }
                        }
                        if (now[j]==0&&now[j+1]!=0){
                            if (now[j+1]==1){
                                nex[j]=1, nex[j+1]=0; join(num);
                                nex[j]=0, nex[j+1]=2; join(num);
                            }
                            else {
                                nex[j]=2, nex[j+1]=0; join(num);
                                nex[j]=0, nex[j+1]=0; join(num);
                            }
                        }
                        if (now[j]==1&&now[j+1]==1){
                            nex[j]=0, nex[j+1]=0; join(num);
                        }
                    }
                }
                g[f1].clear(), f[f1].clear();
                for (unsigned k=0; k<g[f2].size(); k++) h[g[f2][k]]=-1;
                swap(f1,f2);
            }
            for (unsigned k=0; k<g[f1].size(); k++)     g[f1][k]<<=2;
        }
        for (unsigned i=0; i<g[f1].size(); i++)
            if (g[f1][i]==0){
                printf("%d
    ",f[f1][i]);
                return 0;
            }
        printf("0
    ");
        return 0;
    }
    
  • 相关阅读:
    close 不弹出对话框
    ASP.NET会话(Session)保存模式
    ASP.NET页面刷新后滚动条保留在刷新前的位置 MaintainScrollPositionOnPostback
    CSS实现垂直居中的5种方法
    ExpandStackTrace
    HttpTunnel
    PropertyAccess类 Linq.Expressions 实现
    DatagramResolver
    AsyncUdpClient 类
    C# LockFreeStack类
  • 原文地址:https://www.cnblogs.com/Vanisher/p/9135955.html
Copyright © 2011-2022 走看看