这是一道基于状态压缩的动态规划,但应该是这类题中最简单的了。 我们按行递推,将每行的状态用二进制表示出来。这就要求我们进行预处理,记录每个状态上一行的可行状态。这样的动态规划时间复杂度极低。 program corn_field; const pnum=1000000000; maxn=12; maxm=12; type pointer=^node; node=record data:longint; next:pointer; end; var link:array[0..1 shl maxm] of pointer; use:array[0..maxn] of longint; f:array[0..maxn,0..1 shl maxm] of longint; n,m,ans,max:longint; procedure init; var i,j,t:longint; ch:char; begin fillchar(use,sizeof(use),0); readln(n,m); for i:=1 to n do for j:=1 to m do begin repeat read(ch); until (ch='1') or (ch='0'); t:=ord(ch='1'); use[i]:=use[i] shl 1 + t; end; end; procedure prework; var i,j:longint; p:pointer; begin ans:=0; max:=1 shl m - 1; fillchar(f,sizeof(f),0); f[0,0]:=1; for i:=0 to max do begin link[i]:=nil; if (i and (i shl 1)<>0) or (i and (i shr 1)<>0) then continue; for j:=0 to max do if i and j=0 then begin new(p); p^.data:=j; p^.next:=link[i]; link[i]:=p; end; end; end; procedure dp; var i,k:longint; p:pointer; begin for i:=1 to n do for k:=0 to max do begin if k or use[i]<>use[i] then continue; p:=link[k]; while p<>nil do begin inc(f[i,k],f[i-1,p^.data]); f[i,k]:=f[i,k] mod pnum; p:=p^.next; end; end; end; procedure outit; var i:longint; begin for i:=0 to max do begin inc(ans,f[n,i]); ans:=ans mod pnum; end; writeln(ans); end; begin assign(input,'a.in'); reset(input); assign(output,'a.out'); rewrite(output); init; prework; dp; outit; close(input); close(output); end.