bzoj 1814: Ural 1519 Formula 1 插头dp经典题

  用的括号序列,听说比较快。

  然并不会预处理,只会每回暴力找匹配的括号。

  

  1 #include<iostream>
  2 #include<cstdio>
  3 #include<cstring>
  4 #include<algorithm>
  5 #define N 199917
  6 #define ll long long
  7 #define bp 1<<bit[j-1]
  8 #define bq 1<<bit[j]
  9 using namespace std;
 10 int n,m;
 11 int map[15][15];
 12 int head[50006],num,ver[N],nxt[N],tot[2],hash[2][N];
 13 ll f[2][N];
 14 int now,pre;
 15 int bit[20];
 16 int edx,edy;
 17 bool ed(int x,int y)
 18 {
 19     return x==edx&&y==edy;
 20 }
 21 void add(int s,ll d)
 22 {
 23     int a=s%50000;
 24     for(int i=head[a];i;i=nxt[i])
 25     {
 26         if(hash[now][ver[i]]==s)
 27         {
 28             f[now][ver[i]]+=d;
 29             return ;
 30         }
 31     }
 32     tot[now]++;hash[now][tot[now]]=s;
 33     f[now][tot[now]]=d;
 34     num++;nxt[num]=head[a];head[a]=num;ver[num]=tot[now];
 35     return ;
 36 }
 37 
 38 int main()
 39 {
 40     for(int i=1;i<=20;i++)bit[i]=2*i;
 41     scanf("%d%d",&n,&m);
 42     char s[15];
 43     for(int i=1;i<=n;i++)
 44     {
 45         scanf("%s",s);
 46         for(int j=1;j<=m;j++)
 47         {
 48             if(s[j-1]=='*')map[i][j]=0;
 49             else map[i][j]=1;
 50         }
 51     }
 52     bool flag=0;
 53     for(int i=n;i>=1;i--)
 54     {
 55         for(int j=m;j>=1;j--)
 56         {
 57             if(map[i][j])
 58             {
 59                 edx=i,edy=j;break;
 60             }
 61         }
 62         if(edx)break;
 63     }
 64     now=1;pre=0;
 65     f[now][1]=1;tot[now]=1;hash[now][1]=0;
 66     for(int i=1;i<=n;i++)
 67     {
 68         for(int j=1;j<=tot[now];j++)hash[now][j]<<=2;
 69         for(int j=1;j<=m;j++)
 70         {
 71             now^=1;pre^=1;
 72             memset(head,0,sizeof(head));
 73             memset(f[now],0,sizeof(f[now]));
 74             tot[now]=0;num=0;
 75             for(int k=1;k<=tot[pre];k++)
 76             {
 77                 int s=hash[pre][k];ll d=f[pre][k];
 78                 if(!d)continue;
 79                 int p=(s/(bp))&3,q=(s/(bq))&3;
 80                 if(!map[i][j])
 81                 {
 82                     if(!p&&!q)add(s,d);
 83                 }
 84                 else if(!p&&!q)
 85                 {
 86                     if(j<m)add(s^(bp)^(bq+1),d);    
 87                 }
 88                 else if(!p)
 89                 {
 90                     if(q==1)
 91                     {
 92                         add(s^(bq)^(bp),d);
 93                         if(j<m)add(s,d);
 94                     }
 95                     else 
 96                     {
 97                         add(s^(bq+1)^(bp+1),d);
 98                         if(j<m)add(s,d);
 99                     }
100                 }
101                 else if(!q)
102                 {
103                     if(p==1)
104                     {
105                         if(j<m)add(s^(bp)^(bq),d);
106                         add(s,d);
107                     }
108                     else 
109                     {
110                         if(j<m)add(s^(bq+1)^(bp+1),d);
111                         add(s,d);
112                     }
113                 }
114                 else if(p==2)
115                 {
116                     if(q==1)add(s^(bp+1)^(bq),d);
117                     else 
118                     {
119                         int dd=1;
120                         for(int l=j-2;l>=0;l--)
121                         {
122                             if(((s>>bit[l])&3)==2)dd++;
123                             else if(((s>>bit[l])&3)==1)dd--;
124                             if(!dd)
125                             {
126                                 add((s^(bp+1)^(bq+1))-(1<<bit[l])+(1<<bit[l]+1),d);
127                                 break;
128                             }
129                         }
130                     }
131                 }
132                 else if(p==1)
133                 {
134                     if(q==2)
135                     {
136                         if(ed(i,j))add(s^(bp)^(bq+1),d);
137                     }
138                     else
139                     {
140                         int ss=s>>bit[j+1],dd=1;
141                         for(int l=j+1;l<=m;l++,ss>>=2)
142                         {
143                             if((ss&3)==1)dd++;
144                             else if((ss&3)==2)dd--;
145                             if(!dd)
146                             {
147                                 add((s^(bp)^(bq))-(1<<bit[l]+1)+(1<<bit[l]),d);
148                                 break;
149                             }
150                         }
151                     }
152                 }
153             }
154         }
155     }
156     ll ans=0;
157     for(int i=1;i<=tot[now];i++)
158     {
159         if(hash[now][ver[i]]==0)ans=f[now][ver[i]];
160     }
161     printf("%lld
",ans);
162     return 0;
163 }
原文地址:https://www.cnblogs.com/ezyzy/p/6486070.html