zoukankan      html  css  js  c++  java
  • bzoj3125: CITY 题解

    3125: CITY

    Time Limit: 10 Sec  Memory Limit: 128 MB
    Submit: 486  Solved: 213
    [Submit][Status][Discuss]

    Description

    小明和小华要参加NOI,踏上了去X市的火车。
    小明望着窗外的田野,大楼,工厂缓缓后退,在思考着什么。
    这时,对面的小华拿出手机对着他说:“看!我们在这个位置!”
    小明望着手机上显示的地图,城市被接到分割成各个方块,而自己所在的点在慢慢移动。
    他突然意识到自己甚至还没游历过这个自己所在的小城市,学校和家貌以及之间来回的道路似乎成了这个小城的唯一印象。
    若我把它们全部走一圈,可能要仔细计划下吧……不,那么多方案,其实我应该早能做到了吧……小明在心里对自己说。
     

    Input

    第一行有两个数N, M表示地图被分割成N*M个块,接下来有N行,每行有M个字符。
     .  表示这个块可以通过
     - 表示这个块只可以左右通过
     | 表示这个块只可以上下通过
     # 表示这个块不能通过
    (从每个块只能走到其上下左右相邻的四个块)
     

    Output

    一个数,表示小明把所以可以通过的块都经过且只经过一次并回到原地的方案数。
     

    Sample Input

    Sample 1
    2 2
    ..
    ..


    Sample 2
    Input:
    4 4
    ....
    ..-.
    ....
    ....

    Sample Output

    Output 1
    1


    Output 2
    1

    HINT

    数据范围: 0 < N, M < 13 不保证答案在long 范围之内

    Source

      联赛后第一次写题解……

      这道题可以说得上是插头DP裸题了,话说最早接触插头DP是在学基础状压的时候误打误撞看到了CDQ的论文,差点入坑,然而最后我还是得入一下。

      这道题比较特殊的就是‘-’ ‘|’这两个设定,但其实也很容易,我们只要在转移的时候进行特判,‘-’只能接左插头,‘|’只能接上插头。其余转移同理。但是要注意的是由于许多转移代码大体结构一样,可以直接复制粘贴,但是细节还是要去检查一下,我因为特判粘贴后位置改变却没发现调了两个小时。

      1 #include <iostream>
      2 #include <cstdlib>
      3 #include <cstdio>
      4 #include <cstring>
      5 #include <algorithm>
      6 #include <cmath>
      7 #define N 15
      8 using namespace std;
      9 int n,m,ma[N][N],zz,tot[1594330];
     10 char bb[N];
     11 int xp[N],b[1594330],dl[1594330];
     12 long long f[2][1594330],ans;
     13 bool check(int x,int t,int sum)
     14 {
     15     if(sum<0) return 0;
     16     if(x==m+1)
     17         return sum==0;
     18     if(b[t/xp[x]]==1) return check(x+1,t,sum+1);
     19     else if(b[t/xp[x]]==2) return check(x+1,t,sum-1);
     20     else return check(x+1,t,sum);
     21 }
     22 int main()
     23 {
     24     int nn,mm;
     25     scanf("%d%d",&n,&m);
     26     for(int i=1;i<=n;i++)
     27     {
     28         scanf("%s",bb+1);
     29         for(int j=1;j<=m;j++)
     30         {
     31             if(bb[j]=='.') ma[i][j]=1,nn=i,mm=j;
     32             else if(bb[j]=='-') ma[i][j]=2,nn=i,mm=j;
     33             else if(bb[j]=='|') ma[i][j]=3,nn=i,mm=j;
     34         }
     35     }
     36     xp[0]=1;
     37     for(int i=1;i<=m+1;i++) xp[i]=xp[i-1]*3;
     38     for(int i=0;i<xp[m+1];i++) b[i]=i%3;
     39     for(int i=0;i<xp[m+1];i++)
     40     {
     41         if(check(0,i,0))
     42         {
     43             zz++;
     44             tot[zz]=i;
     45             dl[i]=zz;
     46         }
     47     }
     48     int now=1,la=0;
     49     f[1][1]=1;
     50     for(int i=1;i<=n;i++)
     51     {
     52         for(int j=1;j<=m;j++)
     53         {
     54             la^=1,now^=1;
     55             memset(f[now],0,sizeof(f[now]));
     56             int p,q,x=xp[j-1],y=xp[j],t;
     57             for(int k=1;k<=zz;k++)
     58             {
     59                 p=b[tot[k]/x],q=b[tot[k]/y];
     60                 t=tot[k]-p*x-q*y;
     61                 if(ma[i][j])
     62                 {
     63                     if(!p&&!q)
     64                     {
     65                         if(ma[i][j]==1&&dl[t+x+(y<<1)]) f[now][dl[t+x+(y<<1)]]+=f[la][k];
     66                     }
     67                     else if(!q)
     68                     {
     69                         if(ma[i][j]!=3)
     70                         {
     71                             if(j!=m&&dl[t+(y<<(p-1))]) f[now][dl[t+(y<<(p-1))]]+=f[la][k];
     72                             if(i!=n&&ma[i][j]==1&&dl[t+(x<<(p-1))]) f[now][dl[t+(x<<(p-1))]]+=f[la][k];
     73                         }
     74                     }
     75                     else if(!p)
     76                     {
     77                         if(ma[i][j]!=2)
     78                         {
     79                             if(j!=m&&ma[i][j]==1&&dl[t+(y<<(q-1))]) f[now][dl[t+(y<<(q-1))]]+=f[la][k];
     80                             if(i!=n&&dl[t+(x<<(q-1))]) f[now][dl[t+(x<<(q-1))]]+=f[la][k];
     81                         }
     82                     }
     83                     else if(p==1&&q==2)
     84                     {
     85                         if(!t&&i==nn&&j==mm) ans+=f[la][k];
     86                     }
     87                     else if(p==2&&q==1)
     88                     {
     89                         if(ma[i][j]==1)
     90                         {
     91                             if(dl[t]) f[now][dl[t]]+=f[la][k];
     92                         }
     93                     }
     94                     else if(p==1&&q==1)
     95                     {
     96                         if(ma[i][j]==1)
     97                         {
     98                             int u,tmp;
     99                             for(u=j+1,tmp=0;u<=m&&tmp>=0;tmp+=(b[t/xp[u]]==1)-(b[t/xp[u]]==2),u++);
    100                             u--;
    101                             if(t-xp[u]<0) continue;
    102                             if(dl[t-xp[u]]) f[now][dl[t-xp[u]]]+=f[la][k];
    103                         }
    104                     }
    105                     else if(p==2&&q==2)
    106                     {
    107                         if(ma[i][j]==1)
    108                         {
    109                             int u,tmp;
    110                             for(u=j-2,tmp=0;u>0&&tmp>=0;tmp+=(b[t/xp[u]]==2)-(b[t/xp[u]]==1),u--);
    111                             u++;
    112                             if(dl[t+xp[u]]) f[now][dl[t+xp[u]]]+=f[la][k];
    113                         }
    114                     }
    115                 }
    116                 else
    117                 {
    118                     if(!p&&!q&&dl[t]) f[now][dl[t]]+=f[la][k];
    119                 }
    120             }
    121         }
    122         for(int j=zz;j>=1;j--)
    123         {
    124             if(b[tot[j]]==0)
    125             {
    126                 if(dl[tot[j]/3]) f[now][j]=f[now][dl[tot[j]/3]];
    127                 else f[now][j]=0;
    128             }
    129             else f[now][j]=0;
    130         }
    131     }
    132     printf("%lld
    ",ans);
    133     return 0;
    134 }
    View Code
  • 相关阅读:
    WML
    CocoaPods install 安装
    刷新控件,审核
    UIImageView
    课堂练习——返回一个一维整数数组中最大子数组的和
    团队与题目介绍
    学习进度条05
    软件工程结对作业02
    课堂练习——返回一个整数数组中最大子数组的和
    学习进度条04
  • 原文地址:https://www.cnblogs.com/liutianrui/p/8169009.html
Copyright © 2011-2022 走看看