# BZOJ2595:[WC2008]游览计划

## Output

z  ‘_’（下划线）表示该方块没有安排志愿者；
z  ‘o’（小写英文字母o）表示该方块安排了志愿者；
z  ‘x’（小写英文字母x）表示该方块是一个景点；

4 4
0 1 1 0
2 5 5 1
1 5 5 1
0 1 1 0

6
xoox
___o
___o
xoox

## HINT

对于100%的数据，N,M,K≤10，其中K为景点的数目。输入的所有整数均在[0,2^16]的范围内

（其实有种更优的DP写法，外加PASCAL在BZOJ中不享有明显的O2优化）

 1 const
2   fx:array[0..3]of longint=(-1,0,1,0);
3   fy:array[0..3]of longint=(0,-1,0,1);
4 var
5   i,j,k:longint;
6   n,m,ans1,ans2,cnt,s,e,fro1,fro2,to1,to2,pos:longint;
7   map,map2:array[0..10,0..10]of longint;
8   a:array[0..10,0..10,0..1024,0..3]of longint;
9   bo:array[0..10,0..10,0..1024]of longint;
10   f:array[0..1000001,1..3]of longint;
11 procedure ss(x,y,z:longint);
12 begin
13   map2[x,y]:=1;
14   if(a[x,y,z,1]=0)or(a[x,y,z,2]=0)then exit;
15   ss(x,y,a[x,y,z,3]);
16   ss(a[x,y,z,1],a[x,y,z,2],z xor a[x,y,z,3]);
17 end;
18 procedure wh(x,y:longint);
19 begin
20   if x>cnt then
21   begin
22     if a[fro1,fro2,pos,0]+a[to1,to2,y,0]<a[to1,to2,pos or y,0] then
23     begin
24       a[to1,to2,pos or y,0]:=a[fro1,fro2,pos,0]+a[to1,to2,y,0];
25       a[to1,to2,pos or y,1]:=fro1; a[to1,to2,pos or y,2]:=fro2;
26       a[to1,to2,pos or y,3]:=y;
27       if bo[to1,to2,pos or y]=0 then
28       begin
29         bo[to1,to2,pos or y]:=1;
30         inc(e); if e=1000001 then e:=1;
31         f[e,1]:=to1; f[e,2]:=to2; f[e,3]:=pos or y;
32       end;
33     end;
34     if a[fro1,fro2,pos,0]+a[to1,to2,y,0]<a[fro1,fro2,pos or y,0] then
35     begin
36       a[fro1,fro2,pos or y,0]:=a[fro1,fro2,pos,0]+a[to1,to2,y,0];
37       a[fro1,fro2,pos or y,1]:=to1; a[fro1,fro2,pos or y,2]:=to2;
38       a[fro1,fro2,pos or y,3]:=pos;
39       if bo[fro1,fro2,pos or y]=0 then
40       begin
41         bo[fro1,fro2,pos or y]:=1;
42         inc(e); if e=1000001 then e:=1;
43         f[e,1]:=fro1; f[e,2]:=fro2; f[e,3]:=pos or y;
44       end;
45     end;
46     exit;
47   end;
48   if pos and(1 shl(x-1))=0 then
49   wh(x+1,y or(1 shl(x-1)));
50   wh(x+1,y);
51 end;
52 begin
54   for i:=1 to n do
55   for j:=1 to m do
56   for k:=0 to 1023 do a[i,j,k,0]:=maxlongint div 2;
57   for i:=1 to n do
58   for j:=1 to m do
59   begin
61     if map[i,j]=0 then
62     begin
63       inc(e); inc(cnt); f[e,1]:=i; f[e,2]:=j; f[e,3]:=1 shl(cnt-1);
64       a[i,j,f[e,3],0]:=0; bo[i,j,f[e,3]]:=1;
65     end else
66     begin
67       inc(e); f[e,1]:=i; f[e,2]:=j; f[e,3]:=0;
68       a[i,j,0,0]:=map[i,j]; bo[i,j,0]:=1;
69     end;
70   end;
71   a[0,0,(1 shl cnt)-1,0]:=maxlongint;
72   while s<>e do
73   begin
74     inc(s); if s=1000001 then s:=1;
75     fro1:=f[s,1]; fro2:=f[s,2]; pos:=f[s,3];
76     if(pos=(1 shl cnt)-1)and(a[fro1,fro2,pos,0]<a[ans1,ans2,pos,0])
77     then begin ans1:=fro1; ans2:=fro2; end;
78     bo[fro1,fro2,pos]:=0;
79     for i:=0 to 3 do
80     if(fro1+fx[i]>=1)and(fro1+fx[i]<=n)and(fro2+fy[i]>=1)and(fro2+fy[i]<=m)
81     then begin
82       to1:=fro1+fx[i]; to2:=fro2+fy[i];
83       wh(1,0);
84     end;
85   end;
86   writeln(a[ans1,ans2,(1 shl cnt)-1,0]);
87   ss(ans1,ans2,(1 shl cnt)-1);
88   for i:=1 to n do
89   begin
90     for j:=1 to m do
91     begin
92       if map[i,j]=0 then write('x')
93       else if map2[i,j]=1 then write('o')
94       else write('_');
95     end;
96     writeln;
97   end;
98 end.
View Code
posted @ 2017-01-06 09:58  GhoStreach  阅读(86)  评论(0编辑  收藏  举报