bzoj2331 : [SCOI2011]地板 2011-12-20

2331: [SCOI2011]地板Time Limit: 5 Sec  Memory Limit: 128 MB
Submit: 128  Solved: 54
[Submit][Status][Discuss]Description

lxhgww的小名叫“小L”,这是因为他总是很喜欢L型的东西。小L家的客厅是一个的矩形,现在他想用L型的地板来铺满整个客厅,客厅里有些位置有柱子,不能铺地板。现在小L想知道,用L型的地板铺满整个客厅有多少种不同的方案?

需要注意的是,如下图所示,L型地板的两端长度可以任意变化,但不能长度为0。铺设完成后,客厅里面所有没有柱子的地方都必须铺上地板,但同一个地方不能被铺多次。

Input

输入的第一行包含两个整数,R和C,表示客厅的大小。

接着是R行,每行C个字符。’_’表示对应的位置是空的,必须铺地板;’*’表示对应的位置有柱子,不能铺地板。

Output

输出一行,包含一个整数,表示铺满整个客厅的方案数。由于这个数可能很大,只需输出它除以20110520的余数。

Sample Input2 2

*_

__

Sample Output1

HINT

R*C<=100

Source

Day1

——————————————————————

和Ural 1519 Formula 1差不多。就是状态转移不一样,详见程序。

——————————————————————

  1 Program Stone;
  2 
  3 var i,j,k,l,n,m:longint;
  4 
  5     map:array[1..50,1..50]of char;
  6 
  7     f:array[0..1,1..200000]of record opt,v:longint;end;
  8 
  9     o:array[0..1,0..200000]of longint;
 10 
 11     q:array[0..12]of longint;
 12 
 13     t1,t2,lap,num1,num2,opt,tmp:longint;
 14 
 15  procedure init;
 16 
 17  var i,j:longint;
 18 
 19   begin
 20 
 21       readln(n,m);         //因为n*m<=100,所以必要时需要将旋转一下图。
 22 
 23    if m<n then for i:=1 to n do
 24 
 25                  begin
 26 
 27                    for j:=1 to m do
 28 
 29                     read(map[i,j]);
 30 
 31                    readln;
 32 
 33                  end
 34 
 35           else begin
 36 
 37                  for i:=1 to n do
 38 
 39                   begin
 40 
 41                     for j:=1 to m do
 42 
 43                       read(map[j,i]);
 44 
 45                     readln;
 46 
 47                   end;
 48 
 49                  i:=n;n:=m;m:=i;
 50 
 51                end;
 52 
 53   end;
 54 
 55  
 56 
 57  Function refer(opt,x:longint):longint;
 58 
 59   begin
 60 
 61     refer:=opt div q[x-1] mod 3;
 62 
 63   end;
 64 
 65  
 66 
 67  Procedure update(opt,v:longint);
 68 
 69   begin
 70 
 71     if (j=m)and(refer(opt,m+1)<>0) then exit;
 72 
 73     if o[1-lap,opt]=0 then begin
 74 
 75                              inc(num2);
 76 
 77                              o[1-lap,opt]:=num2;
 78 
 79                              f[1-lap,num2].opt:=opt;
 80 
 81                              f[1-lap,num2].v:=v;
 82 
 83                            end
 84 
 85                       else f[1-lap,o[1-lap,opt]].v:=(v+f[1-lap,o[1-lap,opt]].v)mod 20110520;
 86 
 87   end;
 88 
 89  
 90 
 91  Function change(opt,x,s:longint):longint;
 92 
 93   begin
 94 
 95     change:=opt+(s-opt div q[x-1] mod 3)*q[x-1];
 96 
 97   end;
 98 
 99 Begin
100 
101  assign(input,'input.in');reset(input);
102 
103   init;
104 
105   q[0]:=1;
106 
107   for i:=1 to m+1 do q[i]:=q[i-1]*3;
108 
109   lap:=0;num1:=1;
110 
111   f[lap,1].v:=1;f[lap,1].opt:=0;
112 
113   o[lap,0]:=1;
114 
115   for i:=1 to n do
116 
117    for j:=1 to m do
118 
119     begin
120 
121        for k:=1 to num1 do
122 
123         begin
124 
125           opt:=f[lap,k].opt;
126 
127           if j=1 then opt:=opt*3;
128 
129           t1:=refer(opt,j);
130 
131           t2:=refer(opt,j+1);
132 
133           if (t1=0)and(t2=0) then           //状态转移
134 
135             begin
136 
137               if map[i,j]='*' then begin update(opt,f[lap,k].v);continue;end;
138 
139               tmp:=change(change(opt,j,1),j+1,1);
140 
141               update(tmp,f[lap,k].v);
142 
143               tmp:=change(change(opt,j,0),j+1,2);
144 
145               update(tmp,f[lap,k].v);
146 
147               tmp:=change(change(opt,j,2),j+1,0);
148 
149               update(tmp,f[lap,k].v);
150 
151               continue;
152 
153             end;
154 
155           if (map[i,j]='*')or(t1+t2=3)or((t1=1)and(t2=1)) then continue;//淘汰状态
156 
157           if (t1=2)and(t2=2) then
158 
159              begin
160 
161                 tmp:=change(change(opt,j,0),j+1,0);
162 
163                 update(tmp,f[lap,k].v);
164 
165                 continue;
166 
167              end;
168 
169           if (t1=0)or(t2=0) then
170 
171               begin
172 
173                 tmp:=change(change(opt,j,t2),j+1,t1);
174 
175                 update(tmp,f[lap,k].v);
176 
177                 if t1+t2<>2 then
178 
179                   begin
180 
181                     tmp:=change(change(opt,j,0),j+1,0);
182 
183                     update(tmp,f[lap,k].v);
184 
185                   end
186 
187                   else
188 
189                   begin
190 
191                     tmp:=change(change(opt,j,t1 div 2),j+1,t2 div 2);
192 
193                     update(tmp,f[lap,k].v);
194 
195                   end;
196 
197               end;
198 
199         end;
200 
201       for k:=1 to num1 do o[lap,f[lap,k].opt]:=0;
202 
203       lap:=1-lap;num1:=num2;num2:=0;
204 
205     end;
206 
207   writeln(f[lap,o[lap,0]].v);
208 
209  close(input);
210 
211 end.

 

posted on 2016-03-02 20:08  Yesphet  阅读(342)  评论(0编辑  收藏  举报