BZOJ1814: Ural 1519 Formula 1(插头Dp)

Description

Regardless of the fact, that Vologda could not get rights to hold the Winter Olympic games of 20**, it is well-known, that the city will conduct one of the Formula 1 events. Surely, for such an important thing a new race circuit should be built as well as hotels, restaurants, international airport - everything for Formula 1 fans, who will flood the city soon. But when all the hotels and a half of the restaurants were built, it appeared, that at the site for the future circuit a lot of gophers lived in their holes. Since we like animals very much, ecologists will never allow to build the race circuit over the holes. So now the mayor is sitting sadly in his office and looking at the map of the circuit with all the holes plotted on it. Problem Who will be smart enough to draw a plan of the circuit and keep the city from inevitable disgrace? Of course, only true professionals - battle-hardened programmers from the first team of local technical university!.. But our heroes were not looking for easy life and set much more difficult problem: "Certainly, our mayor will be glad, if we find how many ways of building the circuit are there!" - they said. It should be said, that the circuit in Vologda is going to be rather simple. It will be a rectangle N*M cells in size with a single circuit segment built through each cell. Each segment should be parallel to one of rectangle's sides, so only right-angled bends may be on the circuit. At the picture below two samples are given for N = M = 4 (gray squares mean gopher holes, and the bold black line means the race circuit). There are no other ways to build the circuit here. 一个 m * n 的棋盘,有的格子存在障碍,求经过所有非障碍格子的哈密顿回路个数

Input

The first line contains the integer numbers N and M (2 ≤ N, M ≤ 12). Each of the next N lines contains M characters, which are the corresponding cells of the rectangle. Character "." (full stop) means a cell, where a segment of the race circuit should be built, and character "*" (asterisk) - a cell, where a gopher hole is located.

Output

You should output the desired number of ways. It is guaranteed, that it does not exceed 2^63-1.

Sample Input

4 4
**..
....
....
....

Sample Output

2

解题思路:

发现一个格点一定有一进一出,就可以3进制表示括号序列轮廓线Dp就好了。

把该存的存入map/Hash表中,元素访问状态转移,要写好编码和解码。3进制改用4进制。

分类讨论一下,10种情况,画个图就好了。

方程只关心最后一个格点,可以滚动掉2维。

代码:(Hash挂链)

  1 #include<cstdio>
  2 #include<vector>
  3 #include<cstring>
  4 #include<algorithm>
  5 typedef long long lnt;
  6 typedef unsigned int uit;
  7 typedef long long unt;
  8 struct int_2{
  9     uit x;
 10     unt y;
 11     int_2(){}
 12     int_2(uit a,unt b){x=a;y=b;}
 13 };
 14 class Fast_map{
 15     #define mod 2333
 16     public:
 17         bool find(uit x)
 18         {
 19             int y=x%mod;
 20             for(int i=0;i<to[y].size();i++)
 21                 if(to[y][i].x==x)
 22                     return true;
 23             return false;
 24         }
 25         void ins(uit x,unt v)
 26         {
 27             int f=x%mod;
 28             to[f].push_back(int_2(x,v));
 29             return ;
 30         }
 31         void add(uit x,unt v)
 32         {
 33             int f=x%mod;
 34             for(int i=0;i<to[f].size();i++)
 35                 if(to[f][i].x==x)
 36                 {
 37                     to[f][i].y+=v;
 38                     return ;
 39                 }
 40             return ;
 41         }
 42         void clear(void)
 43         {
 44             for(int i=0;i<mod;i++)
 45                 to[i].clear();
 46             return ;
 47         }
 48         void start(void)
 49         {
 50             jjj=0;
 51             iii=0;
 52             while(iii<mod&&!to[iii].size())
 53                 iii++;
 54             return ;
 55         }
 56         bool going_on(void)
 57         {
 58             
 59             return iii<mod;
 60         }
 61         void go(void)
 62         {
 63             jjj++;
 64             if(jjj<to[iii].size())
 65                 return ;
 66             jjj=0;
 67             iii++;
 68             while(iii<mod&&!to[iii].size())
 69                 iii++;
 70             return ;
 71         }
 72         int_2 ite(void)
 73         {
 74             return to[iii][jjj];
 75         }
 76         void move(void)
 77         {
 78             for(int i=0;i<mod;i++)
 79                 for(int j=0;j<to[i].size();j++)
 80                     to[i][j].x<<=2;
 81             return ;
 82         }
 83     private:
 84         std::vector<int_2>to[mod];
 85         int iii,jjj;
 86     #undef mod
 87 }dp[2];
 88 int n,m;
 89 int p,q;
 90 int ei,ej;
 91 unt ans;
 92 char cmd[20];
 93 bool mp[15][15];
 94 void update(int i,uit j,unt val)
 95 {
 96     if(!dp[i].find(j))
 97         dp[i].ins(j,val);
 98     else
 99         dp[i].add(j,val);
100     return ;
101 }
102 uit change(uit x,int plc,uit val)
103 {
104     uit ans=x;
105     uit cut=0ul-1ul;
106     cut^=(1<<(plc<<1));
107     cut^=(1<<(plc<<1|1));
108     ans&=cut;
109     ans|=(val<<(plc<<1));
110     return ans;
111 }
112 int main()
113 {
114     memset(mp,0,sizeof(mp));
115     scanf("%d%d",&n,&m);
116     for(int i=1;i<=n;i++)
117     {
118         scanf("%s",cmd+1);
119         for(int j=1;j<=m;j++)
120         {
121             if(cmd[j]=='.')
122             {
123                 mp[i][j]=true;
124                 ei=i,ej=j;
125             }
126         }
127     }
128     p=0,q=1;
129     dp[0].ins(0,1);
130     for(int i=1;i<=n;i++)
131     {
132         for(int j=1;j<=m;j++)
133         {
134             std::swap(p,q);
135             dp[p].clear();
136             for(dp[q].start();dp[q].going_on();dp[q].go())
137             {
138                 int_2 state=dp[q].ite();
139                 uit s=state.x;
140                 unt v=state.y;
141                 uit tl=(s>>((j-1)<<1))&3;
142                 uit tu=(s>>(j<<1))&3;
143                 if(!mp[i][j])
144                 {
145                     if(tl|tu);else
146                         update(p,s,v);
147                 }else{
148                     uit ts;
149                     if(tl==0)
150                     {
151                         if(tu==0)
152                         {
153                             if(mp[i][j+1]&&mp[i+1][j]);else continue;
154                             ts=change(s,j-1,1);
155                             ts=change(ts,j,2);
156                             update(p,ts,v);
157                         }else if(tu==1)
158                         {
159                             if(mp[i+1][j])
160                             {
161                                 ts=change(s,j-1,1);
162                                 ts=change(ts,j,0);
163                                 update(p,ts,v);
164                             }
165                             if(mp[i][j+1])
166                             {
167                                 ts=change(s,j-1,0);
168                                 ts=change(ts,j,1);
169                                 update(p,ts,v);
170                             }
171                         }else{
172                             if(mp[i+1][j])
173                             {
174                                 ts=change(s,j-1,2);
175                                 ts=change(ts,j,0);
176                                 update(p,ts,v);
177                             }
178                             if(mp[i][j+1])
179                             {
180                                 ts=change(s,j-1,0);
181                                 ts=change(ts,j,2);
182                                 update(p,ts,v);
183                             }
184                         }
185                     }else if(tl==1)
186                     {
187                         if(tu==0)
188                         {
189                             if(mp[i+1][j])
190                             {
191                                 ts=change(s,j-1,1);
192                                 ts=change(ts,j,0);
193                                 update(p,ts,v);
194                             }
195                             if(mp[i][j+1])
196                             {
197                                 ts=change(s,j-1,0);
198                                 ts=change(ts,j,1);
199                                 update(p,ts,v);
200                             }
201                         }else if(tu==1)
202                         {
203                             int cnt=1;
204                             for(int kt=j+1;kt<=m;kt++)
205                             {
206                                 if(((s>>(kt<<1))&3)==1)
207                                     cnt++;
208                                 if(((s>>(kt<<1))&3)==2)
209                                     cnt--;
210                                 if(!cnt)
211                                 {
212                                     ts=change(s,kt,1);
213                                     break;
214                                 }
215                             }
216                             ts=change(ts,j-1,0);
217                             ts=change(ts,j,0);
218                             update(p,ts,v);
219                         }else{
220                             if(i==ei&&j==ej)
221                                 ans+=v;
222                         }
223                     }else{
224                         if(tu==0)
225                         {
226                             if(mp[i+1][j])
227                             {
228                                 ts=change(s,j-1,2);
229                                 ts=change(ts,j,0);
230                                 update(p,ts,v);
231                             }
232                             if(mp[i][j+1])
233                             {
234                                 ts=change(s,j-1,0);
235                                 ts=change(ts,j,2);
236                                 update(p,ts,v);
237                             }
238                         }else if(tu==1)
239                         {
240                             ts=change(s,j-1,0);
241                             ts=change(ts,j,0);
242                             update(p,ts,v);
243                         }else{
244                             int cnt=-1;
245                             for(int kt=j-2;kt>=0;kt--)
246                             {
247                                 if(((s>>(kt<<1))&3)==1)
248                                     cnt++;
249                                 if(((s>>(kt<<1))&3)==2)
250                                     cnt--;
251                                 if(!cnt)
252                                 {
253                                     ts=change(s,kt,2);
254                                     break;
255                                 }
256                             }
257                             ts=change(ts,j-1,0);
258                             ts=change(ts,j,0);
259                             update(p,ts,v);
260                         }
261                     }
262                 }
263             }
264         }
265         dp[p].move();
266     }
267     printf("%lld\n",ans);
268     return 0;
269 }

代码(map)

  1 #include<map>
  2 #include<cstdio>
  3 #include<cstring>
  4 #include<algorithm>
  5 typedef long long lnt;
  6 typedef unsigned int uit;
  7 typedef long long unt;
  8 using std::make_pair;
  9 int n,m;
 10 int p,q;
 11 int ei,ej;
 12 unt ans;
 13 char cmd[20];
 14 bool mp[15][15];
 15 std::map<uit,unt>dp[2],ooo;
 16 void update(int i,uit j,unt val)
 17 {
 18     if(dp[i].find(j)==dp[i].end())
 19         dp[i][j]=val;
 20     else
 21         dp[i][j]+=val;
 22     return ;
 23 }
 24 uit change(uit x,int plc,uit val)
 25 {
 26     uit ans=x;
 27     uit cut=0ul-1ul;
 28     cut^=(1<<(plc<<1));
 29     cut^=(1<<(plc<<1|1));
 30     ans&=cut;
 31     ans|=(val<<(plc<<1));
 32     return ans;
 33 }
 34 int main()
 35 {
 36     memset(mp,0,sizeof(dp));
 37     scanf("%d%d",&n,&m);
 38     for(int i=1;i<=n;i++)
 39     {
 40         scanf("%s",cmd+1);
 41         for(int j=1;j<=m;j++)
 42         {
 43             if(cmd[j]=='.')
 44             {
 45                 mp[i][j]=true;
 46                 ei=i,ej=j;
 47             }
 48         }
 49     }
 50     p=0,q=1;
 51     dp[0][0]=1;
 52     for(int i=1;i<=n;i++)
 53     {
 54         for(int j=1;j<=m;j++)
 55         {
 56             std::swap(p,q);
 57             dp[p].clear();
 58             for(std::map<uit,unt>::iterator State=dp[q].begin();State!=dp[q].end();State++)
 59             {
 60                 uit s=State->first;
 61                 unt v=State->second;
 62                 uit tl=(s>>((j-1)<<1))&3;
 63                 uit tu=(s>>(j<<1))&3;
 64                 if(!mp[i][j])
 65                 {
 66                     if(tl|tu);else
 67                         update(p,s,v);
 68                 }else{
 69                     uit ts;
 70                     if(tl==0)
 71                     {
 72                         if(tu==0)
 73                         {
 74                             if(mp[i][j+1]&&mp[i+1][j]);else continue;
 75                             ts=change(s,j-1,1);
 76                             ts=change(ts,j,2);
 77                             update(p,ts,v);
 78                         }else if(tu==1)
 79                         {
 80                             if(mp[i+1][j])
 81                             {
 82                                 ts=change(s,j-1,1);
 83                                 ts=change(ts,j,0);
 84                                 update(p,ts,v);
 85                             }
 86                             if(mp[i][j+1])
 87                             {
 88                                 ts=change(s,j-1,0);
 89                                 ts=change(ts,j,1);
 90                                 update(p,ts,v);
 91                             }
 92                         }else{
 93                             if(mp[i+1][j])
 94                             {
 95                                 ts=change(s,j-1,2);
 96                                 ts=change(ts,j,0);
 97                                 update(p,ts,v);
 98                             }
 99                             if(mp[i][j+1])
100                             {
101                                 ts=change(s,j-1,0);
102                                 ts=change(ts,j,2);
103                                 update(p,ts,v);
104                             }
105                         }
106                     }else if(tl==1)
107                     {
108                         if(tu==0)
109                         {
110                             if(mp[i+1][j])
111                             {
112                                 ts=change(s,j-1,1);
113                                 ts=change(ts,j,0);
114                                 update(p,ts,v);
115                             }
116                             if(mp[i][j+1])
117                             {
118                                 ts=change(s,j-1,0);
119                                 ts=change(ts,j,1);
120                                 update(p,ts,v);
121                             }
122                         }else if(tu==1)
123                         {
124                             int cnt=1;
125                             for(int kt=j+1;kt<=m;kt++)
126                             {
127                                 if(((s>>(kt<<1))&3)==1)
128                                     cnt++;
129                                 if(((s>>(kt<<1))&3)==2)
130                                     cnt--;
131                                 if(!cnt)
132                                 {
133                                     ts=change(s,kt,1);
134                                     break;
135                                 }
136                             }
137                             ts=change(ts,j-1,0);
138                             ts=change(ts,j,0);
139                             update(p,ts,v);
140                         }else{
141                             if(i==ei&&j==ej)
142                                 ans+=v;
143                         }
144                     }else{
145                         if(tu==0)
146                         {
147                             if(mp[i+1][j])
148                             {
149                                 ts=change(s,j-1,2);
150                                 ts=change(ts,j,0);
151                                 update(p,ts,v);
152                             }
153                             if(mp[i][j+1])
154                             {
155                                 ts=change(s,j-1,0);
156                                 ts=change(ts,j,2);
157                                 update(p,ts,v);
158                             }
159                         }else if(tu==1)
160                         {
161                             ts=change(s,j-1,0);
162                             ts=change(ts,j,0);
163                             update(p,ts,v);
164                         }else{
165                             int cnt=-1;
166                             for(int kt=j-2;kt>=0;kt--)
167                             {
168                                 if(((s>>(kt<<1))&3)==1)
169                                     cnt++;
170                                 if(((s>>(kt<<1))&3)==2)
171                                     cnt--;
172                                 if(!cnt)
173                                 {
174                                     ts=change(s,kt,2);
175                                     break;
176                                 }
177                             }
178                             ts=change(ts,j-1,0);
179                             ts=change(ts,j,0);
180                             update(p,ts,v);
181                         }
182                     }
183                 }
184             }
185         }
186         ooo.clear();
187         for(std::map<uit,unt>::iterator j=dp[p].begin();j!=dp[p].end();j++)
188             if(!((j->first)>>(m<<1)))
189                 ooo[((j->first)<<2)]=j->second;
190         dp[p].clear();
191         for(std::map<uit,unt>::iterator j=ooo.begin();j!=ooo.end();j++)
192             dp[p][j->first]=j->second;
193     }
194     printf("%lld\n",ans);
195     return 0;
196 }
posted @ 2018-12-24 20:53  Unstoppable728  阅读(280)  评论(0编辑  收藏  举报