此题一看数据范围就知道是dp 本人得dp状态是f[i,j]为第i行,状态为j(j是一个三进制的数)。j的第l位为1表示a[i-1,l]放了炮兵部队,为2表示a[i-2,l]放了炮兵部队,否则为0。转移方程略!! 代码如下 var i,j,n,m,ans,p:longint; a:array[1..100,1..10]of char; t,now,k:array[-1..10]of longint; f:array[0..1,0..59048]of longint; procedure make(x,y,z:longint); begin if x>m then begin if z>f[p xor 1,y] then begin f[p xor 1,y]:=z; if ans<z then ans:=z; end; exit; end; if k[x]=2 then make(x+1,y,z) else if k[x]=1 then make(x+1,y+t[x]+t[x],z) else begin if a[i,x]='P' then if (k[x-1]<>3)and(k[x-2]<>3) then begin k[x]:=3; make(x+1,y+t[x],z+1); end; k[x]:=0; make(x+1,y,z); end; end; procedure search(x,y:longint); begin if x>m then begin if f[p,y]<>-1 then begin k:=now; make(1,0,f[p,y]); end; exit; end; now[x]:=0; search(x+1,y); if i>1 then if a[i-1,x]='P' then if now[x-2]<>1 then if now[x-1]<>1 then begin now[x]:=1; search(x+1,y+t[x]); end; if i>2 then if a[i-2,x]='P' then if now[x-2]<>2 then if now[x-1]<2 then begin now[x]:=2; search(x+1,y+t[x]+t[x]); end; end; begin assign(input,'cannon.in');reset(input); assign(output,'cannon.out');rewrite(output); readln(n,m); t[1]:=1; for i:=2 to m do t[i]:=t[i-1]*3; for i:=1 to n do begin for j:=1 to m do read(a[i,j]); readln; end; ans:=0; fillchar(now,sizeof(now),0); fillchar(k,sizeof(k),0); fillchar(f[0],sizeof(f[0]),255); i:=1; p:=1; make(1,0,0); for i:=2 to n do begin p:=i and 1 xor 1; fillchar(f[p],sizeof(f[p]),255); p:=p xor 1; search(1,0); end; writeln(ans); close(input); close(output); end.